-
Notifications
You must be signed in to change notification settings - Fork 266
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
docs: portal messaging #2419
Merged
Merged
docs: portal messaging #2419
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
eb66bf1
docs: small misc changes + ordering changes
LHerskind f17c5db
chore: address maddia comments
LHerskind fcc15aa
docs: combine messaging and portals
LHerskind bcd333e
chore: address maddia comments
LHerskind f1e3846
chore: forgot 🧚
LHerskind 20e34ae
chore: address comments + add snippet for linked deploy
LHerskind f1a0f0f
Update main.md
rahul-kothari File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,5 +1,6 @@ | ||||||
--- | ||||||
title: Portals | ||||||
description: Documentation of Aztec's Portals and Cross-chain communication. | ||||||
--- | ||||||
|
||||||
## What is a portal | ||||||
|
@@ -24,32 +25,31 @@ When sending messages, we need to specify quite a bit of information beyond just | |||||
| Secret Hash | `field` (~254 bits) | A hash of a secret that is used when consuming the message on L2. Keep this preimage a secret to make the consumption private. To consume the message the caller must know the pre-image (the value that was hashed) - so make sure your app keeps track of the pre-images! Use the [`computeMessageSecretHash`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec.js/src/utils/secrets.ts) to compute it from a secret. | | ||||||
| Fee | `uint64` | The fee to the sequencer for including the message. This is the amount of ETH that the sequencer will receive for including the message. Note that it is not a full `uint256` but only `uint64`| | ||||||
|
||||||
:::warning | ||||||
Should we discard the use of the L2Actor struct and use the individual fields instead? Might make integrations a tiny bit more pleasent to work with. | ||||||
::: | ||||||
|
||||||
With all that information at hand, we can call the `sendL2Message` function on the Inbox. The function will return a `field` (inside `bytes32`) that is the hash of the message. This hash can be used as an identifier to spot when your message has been included in a rollup block. | ||||||
|
||||||
#include_code send_l1_to_l2_message l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity | ||||||
|
||||||
As time passes, a sequencer will see your tx, the juicy fee provided and include it in a rollup block. Upon inclusion, it is removed from L1, and made available to be consumed on L2. | ||||||
|
||||||
To consume the message, we can use the `consume_l1_to_l2_message` function within the `context` struct. | ||||||
The `msg_key` is the hash of the message produced from the `sendL2Message` call, the `content` is the content of the message, and the `secret` is the pre-image hashed to compute the `secretHash`. | ||||||
|
||||||
#include_code context_consume_l1_to_l2_message /yarn-project/aztec-nr/aztec/src/context.nr rust | ||||||
|
||||||
Computing the `content` might be a little clunky in its current form, as we are still adding a number of bytes utilities. A good example exists within the [Non-native token example](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/hash.nr). | ||||||
- The `msg_key` is the hash of the message returned by the `sendL2Message` call and is used to help the RPC find the correct message. | ||||||
- The `content` is the content of the message, limited to one Field element. For content larger than one Field, we suggest using the `sha256` hash function truncated to a single Field element. `sha256` is suggested as it is cheap on L1 while still being managable on L2. | ||||||
- The `secret` is the pre-image hashed using Pedersen to compute the `secretHash`. | ||||||
- If the `content` or `secret` does not match the entry at `msg_key` the message will not be consumed, and the transaction will revert. | ||||||
|
||||||
:::info | ||||||
The `inputs` that is passed into `consume_l1_to_l2_message` are only temporary, and will be removed in the future when we improve syntax. | ||||||
Note that while the `secret` and the `content` are both hashed, they are actually hashed with different hash functions! | ||||||
::: | ||||||
|
||||||
An example usage of this flow is a token bridge, in the Aztec contract a `mint` function consumes a message from L1 and mints tokens to a user. Note that we are using a private function, as we don't want to expose the user that is receiving the tokens publicly. | ||||||
#include_code context_consume_l1_to_l2_message /yarn-project/aztec-nr/aztec/src/context.nr rust | ||||||
|
||||||
Computing the `content` must be done manually in its current form, as we are still adding a number of bytes utilities. A good example exists within the [Token bridge example](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/util.nr). | ||||||
|
||||||
#include_code non_native_token_mint yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr rust | ||||||
#include_code claim_public /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust | ||||||
|
||||||
After the transaction has been mined, the message is consumed, and the tokens have been minted on Aztec and are ready for use by the user. A consumed message cannot be consumed again. | ||||||
After the transaction has been mined, the message is consumed, a nullifier is emitted and the tokens have been minted on Aztec and are ready for claiming. | ||||||
|
||||||
Since the message consumption is emitting a nullifier the same message cannot be consumed again. The index in the message tree is used as part of the nullifier computation, ensuring that the same content and secret being inserted will be distinct messages that can each be consumed. Without the index in the nullifier, it would be possible to perform a kind of attack known as `Faerie Gold` attacks where two seemingly good messages are inserted, but only one of them can be consumed later. | ||||||
|
||||||
## Passing data to L1 | ||||||
|
||||||
|
@@ -61,7 +61,7 @@ Recall that we mentioned the Aztec contract specifies what portal it is attached | |||||
|
||||||
The portal must ensure that the sender is as expected. One way to do this, is to compute the addresses before deployment and store them as constants in the contract, however a more flexible solution is to have an `initialize` function in the portal contract which can be used to set the address of the Aztec contract. In this model, the portal contract can check that the sender matches the value it has in storage. | ||||||
|
||||||
To send a message to L1 from your Aztec contract, you must use the `message_portal` function on the `context`. When messaging to L1, only the `content` is required (as field). | ||||||
To send a message to L1 from your Aztec contract, you must use the `message_portal` function on the `context`. When messaging to L1, only the `content` is required (as a `Field`). | ||||||
|
||||||
#include_code context_message_portal /yarn-project/aztec-nr/aztec/src/context.nr rust | ||||||
|
||||||
|
@@ -73,8 +73,7 @@ Access control on the L1 portal contract is essential to prevent consumption of | |||||
|
||||||
As earlier, we can use a token bridge as an example. In this case, we are burning tokens on L2 and sending a message to the portal to free them on L1. | ||||||
|
||||||
<!-- TODO: update token standard https://github.com/AztecProtocol/aztec-packages/issues/2177 --> | ||||||
#include_code non_native_token_withdraw yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr rust | ||||||
#include_code exit_to_l1_private yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust | ||||||
|
||||||
When the transaction is included in a rollup block the message will be inserted into the `Outbox`, where the recipient portal can consume it from. When consuming, the `msg.sender` must match the `recipient` meaning that only portal can actually consume the message. | ||||||
|
||||||
|
@@ -88,9 +87,13 @@ As noted earlier, the portal contract should check that the sender is as expecte | |||||
|
||||||
|
||||||
## How to deploy a contract with a portal | ||||||
- Deploy L1 | ||||||
- Deploy l2 | ||||||
- Initialize l1 with l2 address. | ||||||
- Deploy to L1 using Viem, Foundry or your preferred tool; | ||||||
- Deploy to L2 passing in the address of the L1 portal as its portal contract; | ||||||
```typescript | ||||||
const deploymentTx = Contract.deploy(wallet).send({portalContract: tokenPortalAddress}); | ||||||
``` | ||||||
- Initialize l1 with l2 address for access control. | ||||||
|
||||||
|
||||||
## Standards | ||||||
|
||||||
|
@@ -149,7 +152,7 @@ Building on our token example from earlier, this can be called like: | |||||
The example above ensure that the user can cancel their message if it is underpriced. | ||||||
|
||||||
### Designated caller | ||||||
Designating a caller grants the ability to specify who should be able to call a function that consumes a message. This is useful for ordering of batched messages, as we will see shortly. | ||||||
Designating a caller grants the ability to specify who should be able to call a function that consumes a message. This is useful for ordering of batched messages. | ||||||
|
||||||
When performing multiple cross-chain calls in one action it is important to consider the order of the calls. Say for example, that you want to perform a uniswap trade on L1 because you are a whale and slippage on L2 is too damn high. | ||||||
|
||||||
|
@@ -166,21 +169,19 @@ bytes memory message = abi.encodeWithSignature( | |||||
); | ||||||
``` | ||||||
|
||||||
This way, the message can be consumed by the portal contract, but only if the caller is the designated caller. By being a bit clever when specifying the designated caller, we can ensure that the calls are done in the correct order. For the Uniswap example, say that we have token portals implemented as we have done throughout this page, and n Uniswap portal implementing the designated caller: | ||||||
This way, the message can be consumed by the portal contract, but only if the caller is the designated caller. By being a bit clever when specifying the designated caller, we can ensure that the calls are done in the correct order. For the Uniswap example, say that we have token portals implemented as we have done throughout this page, and a Uniswap portal implementing the designated caller. | ||||||
|
||||||
#include_code solidity_uniswap_swap l1-contracts/test/portals/UniswapPortal.sol solidity | ||||||
We require that the Uniswap portal is the caller of the withdraw, and that the uniswap portal implementation is executing the withdraw before the swap. | ||||||
The order of execution can be constrained in the contract. Since all of the messages are emitted to L1 in the same transaction, we can leverage transaction atomicity to ensure success of failure of all messages. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
We could then have withdraw transactions (on L2) where we are specifying the `UniswapPortal` as the caller. Because the order of the calls are specified in the contract, and that it reverts if any of them fail, we can be sure that it will execute the withdraw first, then the swap and then the deposit. Since only the `UniswapPortal` is able to execute the withdraw, we can be sure that the ordering is ensured. However, note that this means that if it for some reason is impossible to execute the batch (say prices moved greatly), the user will be stuck with the funds on L1 unless the `UniswapPortal` implements proper error handling! | ||||||
Note, that crossing the L1/L2 chasm is asynchronous, so there could be a situation where the user has burned their assets on L2 but the swap fails on L1! This could be due to major price movements or the like. In such a case, the user could be stuck with funds on L1 that they cannot get back to L2 unless the portal contract implements a way to properly handle such errors. | ||||||
|
||||||
:::caution | ||||||
Designated callers are enforced at the contract level for contracts that are not the rollup itself, and should not be trusted to implement the standard correctly. The user should always be aware that it is possible for the developer to implement something that looks like designated caller without providing the abilities to the user. | ||||||
::: | ||||||
|
||||||
## Examples of portals | ||||||
|
||||||
- Non-native token (asset bridged from L1) | ||||||
- Token bridge (Portal contract built for L1 -> L2, i.e., a non-native L2 asset) | ||||||
- [Portal contract](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/test/portals/TokenPortal.sol) | ||||||
- [Aztec contract](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr) | ||||||
- Uniswap (swap tokens on L1) | ||||||
- [Portal contract](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/test/portals/UniswapPortal.sol) | ||||||
- [Aztec contract](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr) | ||||||
- [Aztec contract](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.