Epic summary๐ค๐ค
Iโll give a high-level explanation, and happy to point to more formal resources if you want.
Since youโre coming from the Zcash perspective, itโs worth noting that Cantonโs privacy and integrity guarantees differ because they address a different problem. Zcash aims to fulfill Satoshiโs vision of an encrypted Bitcoin, and ZKPs are really the only practical way to achieve that combination of censorship resistance, public verifiability, and issuer-less assets.
The key insight behind Canton is that in almost all real-world use cases, you donโt need public verification. If you assume that every asset has an issuer (an assumption Zcash canโt make by design), you can achieve strong privacy in much simpler and more efficient ways, without the usability, performance, and integrity-bug blast-radius tradeoffs that come with ZKPs. Credit to the Zcash community for being open about these tradeoffs and constantly improving them.
In Canton, the issuer (more precisely, the registrar) can be centralized or decentralized, but you donโt get privacy from that issuer. Thatโs intentional: my bank should know my balance, my custodian should know my holdings, but the public should not. If someone wanted privacy even from the issuer, thatโs where ZKPs would come in. Itโs technically straightforward to integrate into Canton, but so far there has been no demand for it.
Hereโs how Canton achieves privacy. Canton's privacy works on a strict 'need-to-know' basis. Every smart contract explicitly lists the finite set of parties who are entitled to see it. Like Zcash, Canton uses a UTXO-style model rather than accounts, so the ledger state is a collection of contract instances (UTXOs), and each participant only sees the subset they are part of. Once you have selective disclosure at the data model level, consensus becomes much simpler. Canton essentially performs a two-phase commit among all stakeholders of a transaction, where each participant only sees the parts they are authorized to view.
To go a bit deeper, Canton has formal definitions of the contract language and abstract ledger model, which make privacy a composable property of the system. Each transaction can contain multiple sub-transactions, and each sub-transaction can have its own visibility set. Parties involved in one part of a transaction can see only what theyโre entitled to, while still participating in a larger atomic operation that spans others. So, for example, we can swap cash for an asset, and our banks will only see the cash leg while our custodians only see the asset leg. When we first created the language and ledger model, I still assumed we would use ZKPs for consensus. Because of that, Cantonโs smart contract language actually provides an excellent high-level abstraction for a ZKP-based system, if anyone ever wants to build that layer. All of these formal definitions are in the open-source repository. Because of these abstractions, we were able to make Cantonโs consensus Byzantine fault-tolerant while relatively simple, at least for a single synchronizer (which orders transactions without seeing their contents). Canton can also scale horizontally across multiple synchronizers, but thatโs a separate topic.