A UTXO can hold two balances, one balance in SOL and one balance of an arbitrary SPL token. Sol is the fee token in Light Protocol. Relayer fees are paid in SOL.
A key building block of a UTXO is a shielded keypair. The UTXO is tied to a keypair which is necessary to spend the UTXO because its public key is part of the commitment hash, and the circuit of the zero-knowledge proof expects its signature to be part of the nullifier.
- Amounts: an array of amounts corresponding to the assets AmountsHash = poseidonHash(amount, ..., amount[n]);
- Assets: an array of several asset public keys. The first asset is always SOL, the other asset can be any registered SPL asset including an NFT AssetsHash = poseidonHash(asset, ..., asset[n]);
- Blinding: random 31 bytes (to mask the commitment hash)
- Shielded keypair: privateKey and publicKey = PoseidonHash(privateKey)
- Instruction type: the hash of app data defined by an application verifier
- Pool type: the pool type the assets have been deposited to when shielded. The default pool type is [0u8;32].
- Verifier public key: The public key of the app verifier, which can spend this UTXO. It's 0 for normal transactions in system verifiers
- Version ensures that a circuit can distinguish between versions of UTXOs.
- getCommitmentHash(): generates the commitment hash from the UTXO attributes. This hash is inserted into the Merkle tree on-chain. return commitment = poseidonHash(AmountsHash, Keypair.publicKey, Blinding, AssetsHash, InstructionType, PoolType, VerifierPubkey)
- getSignature(): return signature = Keypair.signature(privkey, commitment, merkleTreeLeafIndex);
- getNullifierHash(): return nullifierHash = poseidonHash(commitment, merkleTreeLeafIndex, signature);
The fields instruction type and verifier public key enable Program UTXOs.
- verifierPublicKey allows the developer to tie the verification of a UTXO to the cpi of a specific program verifier. This only works with program-enabled system verifiers (verifier_two). Other verifiers enforce this field to be 0.
- instructionType can be the hash of application data. This field allows application developers to tie specific application data to a UTXO. The correctness of the hash can be checked in the application proof (Broken link).