Lifecycle of a Light transaction
There are three phases to the lifecycle of a Light transaction:
- 1.Off-chain (computing the state transition)
- 2.On-chain (verification of the correctness of the computation)
- 3."Clearing process" / Merkletree update (inserts the output UTXOs into the Merkletree so they can be spent in the next transaction).
The flow described in this guide generally applies to all Light transaction types, including, e.g., shield (entering the Light ecosystem) and unshield (exiting the Light ecosystem) transactions.
Users complete all off-chain actions on their local machines, e.g., browser client or mobile phone.
- 2.Fetch UTXOs: UTXOs (encrypted) are stored in a compressed account, so the user fetches them from the indexer for better performance. The indexer retrieves UTXOs from Solana.
- 4.Create output UTXOs: at the end of a successful transaction, the hashes of new output UTXOs are inserted into a Merkle tree. The creation of output UTXOs depends on the input UTXOs used.
- 6.Transaction Parameters: contain the input and output UTXOs for a transaction. The proof inputs are generated in the following step. Notable inputs in the compilation are Merkle proofs for input UTXOs. These Merkle proofs are generated with the Merkle tree, fetched in the prior step. ( Transaction Parameters)
- 7.Application Transaction Parameters (optional) depend on the application circuit, which defines custom logic like a smart contract (NOTE: this step is optional and omitted when no application is used). (Transaction Parameters)
- 8.Zero-Knowledge Proofs
- 2.Application proof: by proving, ensures the correct execution of the application logic (if applicable).
- 9.Solana Transaction contains both proofs, their public inputs, and relevant accounts such as the Merkle tree state. Input UTXOs are represented as leaves in the Merkle tree.
- 10.Send Transaction:
- 1.Shield -> The user sends the transaction directly to the verifier program.
- 2.Transfer or Unshield -> The user sends instructions to a relayer, who then submits the transaction on their behalf.
- 3.Application execution: can be combined with all actions (shield, transfer, unshield). The default should be transfer.
- 11.Relayer receives instructions, builds a Solana transaction from them, and submits it to the Solana blockchain. In exchange, the relayer receives a fee. Relaying is trustless because all transaction parameters are included in the system-zero-knowledge proof.
- 12.Program Verifier: verifies a custom application proof. (Only invoked when a custom PSP is used)
- 13.System verifier: verifies the system proof, which proves the validity of UTXOs and the inclusion of input UTXOs in the Merkle tree. In a program execution, the system verifier is invoked from the program verifier via CPI. For shields/transfers/unshields, system verifiers are invoked directly.
- 14.Merkle tree: trusts System Verifiers
- 1.queues hashes of UTXOs as Merkle tree leaves in a PDA (leaves are inserted into the tree in a separate batched process called "Clearing process").
- 2.Inserts nullifiers, one for every input-UTXO. Nullifiers are inserted as PDAs which are derived from the nullifier hash. The nullifier is an identifier of a UTXO. It is stored on-chain to prevent double-spending of UTXOs.
- 3.transfers spl tokens (from/to user/Merkle tree PDA)
- 4.transfers sol tokens (from/to user/Merkle tree PDA)
- 5.transfers fee to relayer in SOL.
As soon as phase 2 is completed, the input UTXOs have been spent, and the state transition is mathematically guaranteed. However, to spend the output-UTXOs of the transaction again, the clearing process has to be completed. (For example, if you shield funds to yourself, phase 3 has to be completed before you can then send these funds to another user privately)
A relayer conducts the Merkle tree update to insert the Merkle tree leaves created in at least the most recent previous transaction. The output-UTXOs that were part of the given transactions can only be spent after they are inserted.
- 1.Relayer initializes a Merkle tree update state PDA, computes a Poseidon hash, and, once done, closes the update PDA.
The clearing process is permissionless and can be executed by anyone. The executor receives a reward for completing the clearing process. Generally, this process can be a batched Merkle tree update to amortize compute cost.