UTXO Model

Panther's unique UTXO model

TL;DR

  • UTXOs are used to represent:

    • Digital assets (zAssets)

    • zAccounts

  • To spend or open a zAsset UTXO the spender must provide a private key

This requirement for a unique private key for each UTXO contributes to the Protocol's privacy layer

Introduction

UTXOs underpin the Protocol's privacy-enhancing solution. A UTXO is the hash of a data package committed to a leaf of a Merkle Tree. The commitment of a UTXO on-chain and the data contained therein, is verifiable thanks to a SNARK proof generated at the time of the commit.

It is the commitment of a UTXO data package on-chain that provides the immutable record of a transaction. However, it is only possible to access data contained within the UTXO by providing the correct cryptographic solution.

UTXOs are used in different ways within the Protocol, which makes the "unspent transaction" a misnomer in certain instances. Let's first consider the model that does create "change" or an unspent amount from a transaction by creating a UTXO worth the difference between its value and the amount spent: the zAsset UTXO.

zAsset UTXOs

zAssets represent digital assets as UTXOs. Every UTXO has one โ€œownerโ€ or zAccount able to spend it. This is achieved by including a public (spending) key in the generation of the UTXO commitment, for which the corresponding private (spending) key is only known by the recipient.

Spending UTXOs

During a spend event, the zAccount holder is either receiving an input UTXO, as in they are the recipient of a digital asset; or they are creating an output UTXO, as in they are spending/sending a digital asset.

When Alice transfers a UTXO to Bob, she transfers the UTXO's read and spend rights to Bob. This means that only Bob's zAccount may open and read the UTXO or spend the UTXO.

If a zAccount holder receives a UTXO, they must successfully decrypt the UTXO's commitment. If they are able to calculate the child private spending key (childPrivSpendingKey), then they may spend the UTXO in the future, i.e. transfer ownership of all or part of the value of that UTXO.

This is how the Protocol protects the transactional privacy of the recipient. A transfer of a zAsset from sender to recipient is a non-interactive transfer i.e. the sender and recipient donโ€™t have to communicate in order to facilitate the transaction. The only prerequisite is that the sender knows the recipient's two root public keys (both spending and reading).

To access the receiverโ€™s public keys, the sender's zAccount looks up the user zAccount registry. On zAccount activation, this registry establishes a link between the public root spending key, public reading key, and an EOA (externally owned account) i.e. a wallet address associated with the user. This allows a non-tracable method for the sender to access the receiver's data.

Shielded Pool contract responsibilities on spend

The Shielded Pool contract performs several checks when Alice sends a UTXO to Bob, it:

  • Verifies that there is no double-spend of the UTXO

nullifierHash is calculated correctly and has not been used before

  • Verifies the ZK proof:

    • the opening of the UTXO commitment is correct

    • the Merkle proof is correct

    • the derived identity is entitled to spend the UTXO

      • Child Public Spending Key is derived from the Child Private Spending Key

      • Child Private Spending Key is the same input used in the opening of the UTXO commitment

zAsset transfer: UTXO spend

A zAsset transfer is a non-interactive, asynchronous spend/receive event that involves two UTXO models, the zAsset and the zAccount.

Let's consider the outcome of a spend event that results in the transfer of 1 zAsset UTXO.

The Shielded Pool supports the spending and creation of multiple UTXOs all within a single transaction using a single proof.

As a result of the spender initiating a zAsset transfer to a different zAccount, at least 2 new UTXOs are committed to the Merkle Tree:

  • Token of transaction: zAsset UTXO created to the value of the transfer amount

With a unique key based on the intended recipient's public key

  • Token of transaction: zAsset UTXO representing any change, if a 0 amount i.e. no "unspent" value remains, then no UTXO is created

If Alice has a UTXO representing 5 zETH and sends Bob 2 zETH, the unspent amount is represented by at least 1 UTXO to the value of 3 zETH

  • zAccount UTXO: the sender's zAccount UTXO is updated to deduct the value of asset sent from balance, fee deduction in zZKP, and an increment to their PRP reward

As a result of the receiver (asynchronously) unlocking the UTXO with their key:

  • zAccount UTXO: receivers zAccount UTXO is updated to reflect the value of asset received

In the case that the sender chose to use a Relayer service to increase the privacy set of the transaction, further UTXO updates are implemented to pay the Relayer fee.

Last updated