← Index

Validity-Proof based onchain-offchain hybrid apps

You must've heard about "Zero Knowledge Proofs" in relation to two big blockchain use-case categories: privacy and scaling.

I've written a conceptual introduction to zero knowledge proofs and covered how ZKPs have been used for onchain privacy in my Tornado Cash manual.

This post is a comprehensive walkthrough of how proofs are used for scaling. I've covered this at a high-level in my mental model post on rollups. We'll dive into details in this post. In particular, we'll reference StarkEx, produced by Starkware.

It might help to read the articles linked so far as "pre-requisites". Nevertheless, this post aims for no jargon, no unwarranted conceptual jumps etc. -- I promise (or at least, I try).

"Validity" proofs, not "ZK" proofs

A validity proof is the output of a cryptographic scheme. It is a small piece of data ("proof") that gives you a hard, mathematical guarantee that a given set of computations produces a given result, without the verifying party having to replay the executions to derive the result for themselves.

A zero knowledge proof is the output of a cryptographic scheme. It is a small piece of data ("proof") that lets you verify that a given piece of original data satisfies a given set of constraints, without having to reveal the original data itself.

Both definitions are picking out the same class of proving algorithms, but emphasize different properties of the proving algorithm. So, the term you use to talk about the proving algorithm depends on the property of the proving algorithm that your application relies on.

In the case of privacy applications like Tornado Cash, it is appropriate to use the term "zero knowledge" proofs since the property of the proofs that's key to the privacy application is not having to reveal the original data you're proving something about. In the case of scaling applications, we use the term "validity" proofs, since the property key to scaling applications is that proof validation is significantly cheaper than replaying the computations that the proof is about.

What "scale" are apps looking for?

All blockchains face a throughput-decentralization trade-off.

Thus, we end up with a hard problem: a single blockchain cannot target high throughput without impacting operational cost per node. This also creates a problem for a number of app categories.

Most prominently -- trading. Users hold monetary value in the form of tokens (assets) on a blockchain. This blockchain may have slower transaction confirmation times (compared to sub-millisecond confirmation times of trades on centralized exchanges/orderbooks), since the blockchain trades off performance for decentralization and security guarantees.

The "scale" that blockchain applications want to achieve is essentially the ability to process the throughput (e.g. trades per second) at the levels of their centralized counterparts. The idea being that if performance is nearly equal, a product offering built on decentralized, permissionless infrastructure is better than one built on permissioned, centralized infrastructure.

Achieving scale via validity proofs

Going forward, this post will discuss the scaling applications in the context of building an orderbook app, for two main reasons:

  1. This is a popular app category, where the motivation is clear for building a decentralized version of the product that's just as fast as its centralized counterpart.
  2. We get to use starkex smart-contracts repository which is excellent reference material for an orderbook app.

The focus of this exercise is to walk through the general architecture of applications that use validity proofs to scale. So, we won't get hung up on starkex-implementation-specific details that are not hard facts about how such applications must be architected.

Here's the general strategy that apps employ to achieve this scale through the use of validity proofs.

abstract contract UpdateState is
    StarkExStorage,
    StarkExConstants,
    MStarkExForcedActionState,
    VerifyFactChain,
    MAcceptModifications,
    MFreezable,
    MOperator,
    PublicInputOffsets
{
    
    function updateState(uint256[] calldata publicInput, uint256[] calldata applicationData)
        external
        virtual
        notFrozen
        onlyOperator
    {...}

}

Our discussion so far has largely centered around the rollup-tree\text{rollup-tree}. Let's complete the loop by going over the two other trees that the canonical state smart contract tracks: the validium-tree\text{validium-tree} and order-tree\text{order-tree}.

In conclusion

Blockchains have emerged as great stores of value, be it for their decentralization properties, public auditability, etc. However, blockchains are distributed databases with multiple nodes, and they necessarily face some version of the throughput-decentralization trade-off.

Blockchain applications looking to offer a self-custodial user experience with the throughput and scale of their centralized counterparts can use validity proofs to achieve their desired scale, while securely accessing the liquidity that lives onchain and letting users trade it.

Overall, it is the mechanism of users being able to force actions on the offchain application via interactions directly with the smart contract on the settlement blockchain, that creates a technically and economically 'hard' connection between the offchain application and the onchain smart contract on the settlement blockchain.