|
1 | | -# Integrating your application with aggregation mode |
| 1 | +# Integrating your application with Aligned Aggregation Mode |
2 | 2 |
|
3 | | -This example will guide you through how to integrate your application with aligned Proof Aggregation service. |
| 3 | +This guide demonstrates how to build a minimal L2 application that integrates with Aligned Aggregation Mode. The L2 is private, that is: it does not post state diffs or any data to Ethereum, only commitments. This way, the prover has to prove that: |
| 4 | + |
| 5 | +1. The state database used in the proof must match the commitment stored in the on-chain contract. This is validated by computing the commitment of the received data in the zkvm and then exposing it as a public input. |
| 6 | +2. The users performing the transfers have enough balance |
| 7 | + |
| 8 | +After processing the transfers, the vm computes the commitment of the post state, which is exposed as a public input. The smart contract then updates the on-chain state root. If a user later wants to retrieve their state, the application must return it along with a Merkle proof, so they can verify it against the contract’s state root. |
| 9 | + |
| 10 | +## Further improvements |
| 11 | + |
| 12 | +This is a very basic and minimal L2 design and can be extended. For example: |
| 13 | + |
| 14 | +- Block Support: Add support for batching transactions into blocks and publishing those blocks. |
| 15 | +- Soft Finality: Use the Verification Layer or Fast Mode for faster confirmation of L2 blocks. |
| 16 | +- Hard Finality: Use Aggregation Mode to finalize state transitions with high security. |
| 17 | + |
| 18 | +### How it works: Step by Step |
| 19 | + |
| 20 | +1. Load or initialize the database state. |
| 21 | +2. Load user transfers. |
| 22 | +3. Run the zkvm with db + transfers to perform. |
| 23 | +4. Generate and submit the proof to Aligned. |
| 24 | +5. Wait for the proof to be aggregated. |
| 25 | +6. Call the smart contract function `updateStateTransition`, which: |
| 26 | + 1. Calls `verifyProofInclusion` in the `AlignedProofAggregationService`, which: |
| 27 | + - Computes the proof commitment with the provided `public_inputs` and `program_id` |
| 28 | + - Computes the Merkle Root, using the provided Merkle Proof. |
| 29 | + - Checks the root exists in the aggregation root. |
| 30 | + 2. Verifies that the initial_state_root public input matches the on-chain state. |
| 31 | + 3. If successful, updates the state root with the post_state_root public input. |
| 32 | +7. If the contract call succeeds, updates the local database. |
| 33 | + |
| 34 | +### Usage |
| 35 | + |
| 36 | +#### Requirements |
| 37 | + |
| 38 | +1. [Rust](https://www.rust-lang.org/tools/install): we have tested in v1.85.1 |
| 39 | +2. [Foundry](https://book.getfoundry.sh/getting-started/installation) |
| 40 | +3. [Docker](https://docs.docker.com/engine/): for SP1 prover |
| 41 | + |
| 42 | +#### 1. Create keystore |
| 43 | + |
| 44 | +You can use cast to create a local keystore. If you already have one you can skip this step. |
| 45 | + |
| 46 | +```bash |
| 47 | +cast wallet new-mnemonic |
| 48 | +``` |
| 49 | + |
| 50 | +Then you can import your created keystore using: |
| 51 | + |
| 52 | +```bash |
| 53 | +cast wallet import --interactive <path_to_keystore.json> |
| 54 | +``` |
| 55 | + |
| 56 | +Then you need to obtain some funds to pay for gas and proof verification. |
| 57 | +You can do this by using this [faucet](https://cloud.google.com/application/web3/faucet/ethereum/holesky) |
| 58 | + |
| 59 | +This same wallet is used to send the proof via aligned, so you'll also need to fund it on aligned. Follow this [guide](https://docs.alignedlayer.com/guides/0_submitting_proofs#id-2.-send-funds-to-aligned). |
| 60 | + |
| 61 | +#### 2. Deploy the contract |
| 62 | + |
| 63 | +Generate the base `.env`. For `Holesky` you can run: |
| 64 | + |
| 65 | +```shell |
| 66 | +make gen_env_contract_holesky |
| 67 | +``` |
| 68 | + |
| 69 | +And then in `contracts/.env` you have to complete the missing variables: |
| 70 | + |
| 71 | +- `INITIAL_STATE_ROOT`: you can leave it as it is unless you change the initial state in `crates/l2/db.rs` |
| 72 | +- `PROGRAM_ID`: you need to ensure it matches the one on your machine: |
| 73 | + 1. Run `make generate_program_id` to generate it. |
| 74 | + 2. Check `crates/l2/programs_ids.json` for the ID. |
| 75 | +- `OWNER_ADDRESS`: you have to provide the address of the wallet created in step `1.`. |
| 76 | +- `PRIVATE_KEY`: the private key used for the deployment, it needs to have some funds to pay for the deployment. |
| 77 | + |
| 78 | +Once you have completed the `.env`, you can deploy the contract: |
| 79 | + |
| 80 | +```shell |
| 81 | +make deploy_contract |
| 82 | +``` |
| 83 | + |
| 84 | +Save the output contract address. |
| 85 | + |
| 86 | +#### 3. Run L2 program |
| 87 | + |
| 88 | +Generate the base `.env`. For `Holesky` you can run: |
| 89 | + |
| 90 | +```shell |
| 91 | +make gen_env_l2_holesky |
| 92 | +``` |
| 93 | + |
| 94 | +And complete the variables: |
| 95 | + |
| 96 | +- `BEACON_CLIENT_URL`: A beacon client url, public node usually don't work as they don't support the endpoints to retrieve blob data |
| 97 | +- `PRIVATE_KEY_STORE_PATH`: The path to the keystore created in `1.`. |
| 98 | +- `PRIVATE_KEY_STORE_PASSWORD`: The password of the keystore crated in step `1.`. |
| 99 | +- `STATE_TRANSITION_CONTRACT_ADDRESS`: The address of the contract deployed in step `2.` |
| 100 | + |
| 101 | +Finally, run the L2: |
| 102 | + |
| 103 | +```shell |
| 104 | +make run_l2 |
| 105 | +``` |
| 106 | + |
| 107 | +You should see a transaction receipt in the console and the stateRoot updated on-chain. You can run this process repeatedly, but make sure to not delete the db file, or the application will not be able to prove valid state transitions. |
0 commit comments