On a transparent chain, everyone has complete visibility into every transaction, and this assumption permeates nearly every aspect of existing blockchain tooling. On Penumbra, users experience a kind of “encryption horizon”: they can only see data when in possession of certain key material, defining a limit of visibility beyond which they cannot see. And this horizon will vary by user: for instance, the sender of a transfer may be able to see the entire transaction, while the receiver of the same transfer may only be able to see the funds sent to them. The same data can be viewed from multiple vantage points or perspectives, corresponding to different sets of key material, and giving different insight into the data’s meaning.
This poses a challenge: how can we enable developers to build tools for users to navigate this environment? How can we provide a unified interface for separating decrypted signal from encrypted noise, and conveying a sense of where visibility begins and ends in the context of particular transactions? To meet this challenge, we realized we needed to provide fine-grained modeling of visibility throughout the entire lifecycle of the transaction data. This data modeling is provided by additional data types that take visibility into account: the TransactionPlan
used to create the Transaction
, and the TransactionPerspective
used afterwards to generate a TransactionView
.
The TransactionPlan
contains a complete, plaintext description of all data that will be used to build the transaction. This allows a user or custodian to review the exact effects of a transaction before authorizing it, to provide confidence that the transaction will do what it was intended to do. The signatures required to authorize a transaction can be computed directly from the plan, without building the complete transaction and its zero-knowledge proofs. This means resource-constrained custodians such as hardware wallets can avoid expensive proving operations. The TransactionPlan
is specified as a protobuf message, so it can be serialized, sent across the network, and parsed by tooling in any language, providing a common interface to a wide variety of custody mechanisms.
When building the Transaction
itself, the cleartext data contained in the TransactionPlan
is then either omitted entirely and replaced by opaque commitments, or shielded inside an encrypted payload. Each payload is encrypted with a freshly generated payload key, and the payload key is then encrypted to all relevant parties to the transaction. This allows different parties to have different levels of visibility into the Transaction
, as each payload key corresponds to an independently-encrypted constituent element of the transaction. Each different set of possible decrypted elements in a Transaction
can be specified in a particular TransactionPerspective
, which is a bundle of per-transaction key material and commitment openings, and which can be used to generate the corresponding TransactionView
. Like the TransactionPlan
, the view and perspective are specified as TransactionPerspective and TransactionView protobuf messages.
The TransactionView
created by a specific TransactionPerspective
models a decrypted, interpreted view of a transaction, and is intended to be consumed by ecosystem tools and interfaces. Rather than requiring every ecosystem tool to implement its own logic to decrypt and understand the effects of shielded transactions, tools can consume TransactionView
s without having to support Penumbra-specific cryptography. Because the TransactionPerspective
is a self-contained serializable object, we have the ability to selectively disclose information about specific transactions, rather than disclosing an account’s long-term FullViewingKey
s, which would give access to all past and future activity.
This design allows users to disclose fine-grained selections from their transaction history for accounting, auditing, or compliance purposes. Just as importantly, it also means we can design wallets or frontend interfaces that don’t require access to long term key material, and which allow users to choose to share their visibility into parts of the chain with other applications. The first wallet of this type is the Penumbra Web Wallet developed by the Zpoken team, which is already available for use on our testnets, and which we will be discussing in more detail in a future blog post. The web wallet keeps all spending and viewing keys in a browser extension and only returns specific TransactionView
s to web content, so that a compromised frontend cannot steal a user’s funds or view their future activity.
With these affordances, we hope that users can interact with the Penumbra shielded chain with the same ease as they would with a traditional transparent chain, while accommodating the necessarily-reduced visibility that comes with providing privacy-by-default. We want you to easily see and understand what is yours, while providing the ability to conveniently share what you can see with other parties, to whatever degree you desire. Privacy is about consent, so Penumbra provides robust tooling for selective disclosure under the control of the holder of the relevant viewing key. What you see on-chain is yours to disclose… or leave concealed. 🌙