Notes, Nullifiers, and Trees

Penumbra’s transaction model is derived from the Sapling shielded transaction design, with modifications to support multiple asset types, and several extensions to support additional functionality. The Sapling model is in turn derived from Bitcoin’s unspent transaction output (UTXO) model, in which value is recorded in transaction outputs that record the conditions under which they can be spent.

In Penumbra, value is recorded in notes, which function similarly to UTXOs. Each note specifies (either directly or indirectly) a type of value, an amount of value of that type, a spending key that authorizes spending the note’s value, and a unique nullifier derived from the note’s contents.

However, unlike UTXOs, notes are not recorded as part of the public chain state. Instead, the chain contains a note commitment tree, an incremental Merkle tree containing (public) commitments to (private) notes. Creating a note involves creating a new note commitment, proving that it is well-formed, . Spending a note involves proving that the spent note was previously included in the note commitment tree, using the spending key to demonstrate spend authorization, and revealing the nullifier, which prevents the same note from being spent twice.

Asset types are uniquely identified by an ADR001 name for compatibility with IBC, and Penumbra supports IBC transfers to transfer value into and out of of the zone, allowing Penumbra’s shielded pool to privately record any asset in the Cosmos ecosystem. ADR001 precisely specifies the entire pathway to the origin of any token, but when this precision is not required, we denote the Penumbra bearer tokens for asset XYZ as pXYZ; e.g., transferring ATOM from the Hub to Penumbra results in pATOM.