# ZkApp Design

## Off-chain Storage

The difference and also innovation of zkApps is their use of *“off-chain execution and mostly off-chain state model”*.

* Off-chain execution means every operation is executed on the client machine and then verified by validators with ZK proofs.&#x20;
* For the off-chain state model, zkApps do not store data on-chain directly. Instead, data structures like arrays or key-value maps can be stored indirectly in a smart contract with by being wrapped in Merkle Tree data structures.

To allow the availability this off-chain storage, all information required to reconstruct the Merkle Trees are dispatched/emitted using the concepts of Actions/Events in zkApp, which allow the retrieval of those information through Mina's graphql endpoints.

Moreover, the implementation of the off-chain storage and the storage service for its reconstruction is open-source, allowing anyone to be able to build the Merkle Trees on their own to use the protocol without relying on any service.

## Concurrent Actions

To solve the concurrency problems in Mina protocol, we utilizes the concept of Actions in zkApp with the following design. We defined the lifespan of an action in 3 states:

1. Dispatch - Action is initiated.
2. Rollup (optional) - Actions are compiled and prepared for processing.
3. Process - Action is executed and completed.

The transaction will be defined to have 4 statuses based on the lifespan of above action:

* Tx Sent: Action is pending.
* Tx Succeeded: Action is recorded.
* Rollup Succeeded (optional): Action is compiled with others in a rollup.
* Process Succeeded: Action is fully processed.

There are two primary approaches for implementing zkApps based on the processing needs:

1. Contiguous Processing: zkApps with actions that can be processed in a contiguous sequence within a single recursive proof. This approach does not require a separate roll-up step.
2. Non-Contiguous Processing: zkApps with actions that must be processed in non-contiguous sequences across multiple recursive proofs. These zkApps should utilize the shared RollupContract zkApp for the rollup step.

To not duplicate the task of roll-up, we create a shared contract, which facilitates the rollup process for zkApps by:

* Recording actions dispatched by any zkApp.
* Consolidating actions from all registered zkApps into a single transaction, updating to the latest action states.

This structure ensures efficient and organized processing of actions across multiple zkApps, optimizing transaction throughput and system scalability.
