Skip to content

Commit

Permalink
Merge pull request #484 from o1-labs/417-improve-how-zkapps-work
Browse files Browse the repository at this point in the history
DX: improve How zkApps Work content
  • Loading branch information
barriebyron authored Jul 12, 2023
2 parents 1e14fb3 + b3b79be commit a93893e
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 73 deletions.
130 changes: 61 additions & 69 deletions docs/zkapps/how-zkapps-work.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,153 +24,145 @@ zkApp programmability is not yet available on the Mina Mainnet. You can get star

zkApps run in the latest versions of [Chrome](https://www.google.com/chrome/index.html), [Firefox](https://www.mozilla.org/en-US/firefox/new/), [Edge](https://microsoft.com/edge), and [Brave](https://brave.com/) web browsers.

zkApps are written in TypeScript using the Mina zkApp CLI. Before you follow the guided steps in [How to write a zkApp](how-to-write-a-zkapp), get started by learning how zkApps work.
zkApps are written in TypeScript using the Mina zkApp CLI.

A zkApp consists of two parts:

1) A smart contract
2) A user interface (UI) for users to interact with the zkApp
- A smart contract

- A user interface (UI) for users to interact with the zkApp

<figure>
<img src="/img/3_zkApps_Structure.jpg" width="100%" />
<figcaption>zkApps consists of two parts: 1) a smart contract and 2) a UI (user interface) for users to interact with it.</figcaption>
<img src="/img/3_zkApps_Structure.jpg" width="100%" alt="Diagram showing two parts of a zkApp" />
</figure>

<br />

:::note
- The term _smart contract_ refers to the code written with SnarkyJS.

The term <b>“smart contract”</b> refers to the code written with SnarkyJS.
- The term _zkApp_ refers to the UI + the smart contract.

The term <b>“zkApp”</b> refers to the UI + the smart contract.

:::
## Zero knowledge-based smart contracts

### Zero-knowledge based smart contracts
zkApps are based on zero knowledge proofs (zk-SNARKs). As a zkApp developer, you use the zkApp CLI to scaffold and deploy your project.

Because zkApps are based on **zero-knowledge proofs (zk-SNARKs)**, a zkApp developer writes what is called a **“circuit”**. A circuit is the method from which a **prover function** and a corresponding **verifier function** are derived during the build process.
Provable code is written by using SnarkyJS and generates a prover function and a corresponding verifier function that are derived during the build process.

The **prover function** is the function that executes a smart contracts custom logic.
The prover function is the function that executes a smart contract's custom logic and runs in a user's web browser as part of the zkApp. The prover function generates a proof of the executed code.

The **prover function** runs in a user’s web browser as part of the zkApp. When interacting with a zkApp's UI, users enter any data (e.g. “buy ABC for y price”) required as input to the prover function, which then generates a zero-knowledge proof.
When interacting with a zkApp UI, users enter any data (for example, buy ABC for y price) that is required as input to the prover function, which then generates a zero knowledge proof.

<figure>
<img src="/img/4_zkApps_Prover_Function.jpg" width="90%" />
<figcaption>The prover function is the function which executes a smart contract’s custom logic.</figcaption>
<img src="/img/4_zkApps_Prover_Function.jpg" width="90%" alt="Diagram showing private and public inputs to prover function to create zero knowledge proof" />
</figure>

Both **private inputs** and **public inputs** represent data that must be provided to the prover function when it runs in the users web browser.
Both private inputs and public inputs represent data that must be provided to the prover function when it runs in the user's web browser.

**Private inputs** are not needed again after that point. But **public inputs** must be also provided to the verifier function when it runs on the Mina network, and as such should never be used for data that you want to remain private.
Private inputs are not required again. Because public inputs must also be provided to the verifier function when it runs on the Mina network, public inputs are not used for data that you want to remain private.

The **verifier function** is the function that validates whether a zero-knowledge proof successfully passes all the constraints defined in the prover function. This _always_ runs quickly and efficiently _irrespective of the prover function’s complexity_.
The verifier function validates whether a zero knowledge proof successfully passes all the constraints defined in the prover function. The verifier function _always_ runs quickly and efficiently, irrespective of the prover function's complexity.

Within the Mina network, Mina acts as the verifier and runs the verifier function.

<figure>
<img src="/img/5_zkApps_Verifier_Function.jpg" width="90%" />
<figcaption>The verifier function is the function that validates whether a zero-knowledge proof successfully passes all the constraints defined in the prover function.</figcaption>
<img src="/img/5_zkApps_Verifier_Function.jpg" width="90%" alt="Diagram showing verifier function validation" />
</figure>

### Prover Function & Verification Key
## Prover Function and Verification Key

The zkApp developer writes smart contracts and then uses the `npm run build` command. The build process outputs `smart_contract.js`. From this, you can:
After you write your smart contract, run the `npm run build` command. The build process compiles the TypeScript code into JavaScript and outputs the `smart_contract.js` file.

- Run your prover function to run your smart contract
From this file, you can:

- Run a prover function to run your smart contract
- Generate a verification key to deploy your smart contract

The **prover function** runs in a users web browser.
While the prover function runs in a user's web browser, the verification key lives on-chain for a given zkApp account and is used by the Mina network to verify that a zero knowledge proof has met all constraints defined in the prover. A verification key is required to create a zkApp account.

The **verification key** lives on chain for a given zkApp account and is used by the Mina network to verify that a zero-knowledge proof has met all constraints defined in the prover. A verification key is required in order to create a zkApp account.
You can also use the verifier function or verification key to verify proofs off-chain.

The next two sections go into more detail about how the prover and verifier functions are used when a zkApp is deployed and when users interact with a zkApp.
## Deploy a smart contract

### Deploying a smart contract
Smart contracts are deployed to the Mina network using the Mina zkApp CLI. The deployment process sends a transaction that contains the verification key, an output of the verifier function, to an address on the Mina blockchain.

<figure>
<img src="/img/6_zkApps_DeploySmartContract.jpg" width="75%" alt="Diagram showing deployment of a Mina zkApp smart contract" />
</figure>

<br/>
When a Mina address contains a verification key, it acts as a zkApp account.

To deploy a smart contract to the Mina network, the zkApp developer uses the Mina zkApp CLI. The deployment process sends a transaction that contains the verification key to an address on the Mina blockchain.
A regular Mina account can receive any transactions.

When a Mina address contains a verification key, it acts as a **zkApp account**.
Whereas a regular Mina account can receive any transactions, a zkApp account can only successfully receive transactions that contain a proof that satisfies the verifier function. Any transactions that do not pass the verifier function are rejected by the Mina network.
You can specify [permissions](/zkapps/snarkyjs/permissions) so a zkApp account can successfully receive only transactions that satisfy the verifier function.

:::info
Any transactions that do not pass the verifier function are rejected by the Mina network.

When you deploy to a new Mina address, the Mina Protocol charges a 1 MINA fee for account creation. This fee is unrelated to zkAapps and helps to prevent Sybil or denial of service attacks.
When you deploy to a new Mina address, the Mina Protocol charges a 1 MINA fee for account creation. This fee is unrelated to zkApps and helps to prevent Sybil or denial of service attacks.

:::note
## Deploy a zkApp UI

### Deploying a zkApp UI
A zkApp consists of a smart contract and a UI to interact with it.

<img src="/img/7_zkApps_DeploySmartContract.jpg" width="95%" />
<br></br>
To enable users to interact with your smart contract in a web browser, you build a website UI and then deploy this interactive UI as a static website. Choosing a host that offers a global content delivery network (CDN) ensures the best experience for all of your users.

zkApp developers usually build a UI to allow users to interact with the smart contract and then deploy this interactive UI as a static website. Choosing a host that offers a global content delivery network (CDN) ensures the best experience for all of your users.
<img src="/img/7_zkApps_DeploySmartContract.jpg" width="95%" alt="Diagram of a zkApp that includes JavaScript and the UI" />

Your website must contain the JavaScript version of your smart contract that is output when building your TypeScript smart contract project. For more details, see [how to write a zkApp](how-to-write-a-zkapp).
Your website must contain the JavaScript `smart_contract.js` file that you generated with the `npm run build` command. To learn more, see [How to Write a zkApp](how-to-write-a-zkapp).

<img src="/img/8_zkApps_DeploySmartContract.jpg" width="95%" />
## How users interact with a zkApp

### How users interact with a zkApp
To use a zkApp, users must [Install a Wallet](using-mina/install-a-wallet) that supports interactions with zkApps.

:::info
After a zkApp is deployed to a host (for example, mycoolzkapp.com), users can interact with it:

To use a zkApp, users must [install Auro wallet for Google Chrome](https://www.aurowallet.com). We anticipate other wallets to add support for zkapps in the future.

:::

<br />

Auro is the only wallet that supports zkApp transactions currently. However, we plan to expand support for zkApps to other types of wallets (such as mobile wallets and desktop wallets) in the future.
1. User visits mycoolzkapp.com.
1. User interacts with the zkApp and enters any data as required. (For example, if this were an automated market maker, the user might specify to buy x amount of ABC at y price.)
1. The prover function in the zkApp generates a zero knowledge proof locally using the data entered by the user. This data can be either:

After a zkApp is deployed to a host (e.g. mycoolzkapp.com), users can interact with it:
- Private, the data is never seen by the blockchain
- Public, the data is stored on-chain or off-chain, depending on what the zkApp specified as required for a given use case.

1. User visits mycoolzkapp.com.
2. User interacts with the zkApp and enters any data as required. (For example, if this were an automated market maker, the user might specify to “buy x amount of ABC at y price”.)
3. The prover function in the zkApp generates a zero-knowledge proof locally using the data entered by the user. This data can be either private (which is never be seen by the blockchain) or public (which is stored either on chain or off chain), depending on what the developer specified, as needed for a given use case. Additionally, a list of state updates (called account updates) to be created by this transaction is generated and is associated with this proof.
4. User clicks “submit to chain” in the zkApp UI and their wallet (such as a browser extension wallet) prompts them to confirm sending the transaction. The wallet signs the transaction that contains the proof and associated description of state to update and sends it to the Mina blockchain.
5. When the Mina network receives this transaction, it verifies that the proof successfully passes the verifier method listed on the zkApp account. If the network accepts this transaction, this indicates that this proof and the requested state changes are valid and, as such, are allowed to update the zkApp’s state.
Additionally, a list of state updates (called account updates) to be created by the transaction is generated. The account updates are associated with this proof.
1. User selects “submit to chain” in the zkApp UI.
- The user confirms the transaction on their wallet, such as a browser extension wallet.
- The wallet signs the transaction that contains the proof and the associated description of state to update.
- The wallet sends the transaction to the Mina network.
1. The Mina network receives this transaction and verifies that the proof successfully passes the verifier method listed on the zkApp account. If the network accepts this transaction, then this proof and the requested state changes are valid and are allowed to update the zkApp state.

Because the user’s interaction occurs _locally_ within their web browser (using JavaScript on the client), the user’s privacy is maintained.
The user's privacy is maintained because their interaction occurs locally in a web browser using JavaScript on the client.

### How state is updated on chain

Now you have learned enough to wonder how the state on a zkApp account gets updated on chain.
The zkApp account gets updated on chain.

When the prover function runs in a web browser, the smart contract outputs a proof and some associated data called "account updates" that are sent as part of the transaction when sending a transaction to a zkApp address. The account updates are a JSON plaintext description that describe how to update the state on a zkApp account.
When the prover function runs in a web browser, the smart contract outputs a proof and some associated data called "account updates" that are sent to a zkApp address as part of the transaction. The account updates are a JSON plain text description that describes how to update the state on a zkApp account.

The integrity of these account updates is ensured by passing a hash of the account updates as a public input to the smart contract. The account updates must be present and unmodified for the verification function to pass successfully when it runs on Mina. In this way, the Mina network can confirm the integrity of both the proof and the associated account updates that describe how to update the zkApp account’s state.
The integrity of these account updates is ensured by passing a hash of the account updates as a public input to the smart contract. The account updates must be present and unmodified for the verification function to pass successfully when it runs on Mina. In this way, the Mina network can confirm the integrity of both the proof and the associated account updates that describe how to update the zkApp account state.

### ZkApp state

Two different types of state exist on Mina: on-chain state and off-chain state.
- On-chain state describes state that lives on the Mina blockchain.

On-chain state describes state that lives on the Mina blockchain. Off-chain state describes state stored anywhere else--such as [IPFS](https://ipfs.io/), etc.
- Off-chain state describes state stored anywhere else.

### On-chain state

Each zkApp account provides 8 fields of 32 bytes each of arbitrary storage. You may store anything here as long as it fits in the size provided.

If you anticipate your state to be larger than this, or if the state accumulates per user with your zkApp, then use off-chain state instead.
If you anticipate your state to be larger, or if the state accumulates per user with your zkApp, then use off-chain state instead.

### Off-chain state

:::info

Support for off-chain state will be coming soon.
Off-chain state is not yet supported.

:::

For larger data, you may want to consider storing the root of a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) (or similar data structure) within your zkApps on-chain storage that references additional off-chain state stored elsewhere, in a location of your choosing, such as [IPFS](https://ipfs.io/).
For larger data, you might want to consider storing the root of a [Merkle tree](/zkapps/snarkyjs/merkle-tree) or a similar data structure within your zkApp's on-chain storage that references additional off-chain state stored elsewhere, such as [IPFS](https://ipfs.io/) and others.

When the zkApp runs in a users web browser, it may insert state to an external storage, such as IPFS. When the transaction is sent to the Mina network, if it accepts this zkApp transaction (i.e. this proof & state were valid so the updates are allowed), then the zkApp transaction can update the root of the Merkle tree that is stored on chain.
When the zkApp runs in a user's web browser, it can insert state to an external storage, such as IPFS. When the transaction is sent to the Mina network, if it accepts this zkApp transaction then proof and state are known to be valid valid so the updates are allowed, then the zkApp transaction can update the root of the Merkle tree that is stored on chain.

<img src="/img/9_zkApps_Off-Chain_State.jpg" width="95%" />

### Keep going

On the next page, learn [how to write a zkApp](how-to-write-a-zkapp)!
On the next page, learn [How to write a zkApp](how-to-write-a-zkapp).
8 changes: 4 additions & 4 deletions docs/zkapps/roadmap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ To view all of the commands and start building, run `zk --help`.
- [Local blockchain](/zkapps/snarkyjs-reference/modules/Mina#localblockchain)
- [And more...](/zkapps/snarkyjs-reference)

### Mina zkApp CLI

- [Third-party fee payer accounts for deployment transactions](https://github.com/o1-labs/zkapp-cli/issues/129) can be used across multiple projects

### Data Availability

- [On-chain state](/zkapps/how-to-write-a-zkapp#on-chain-state) — 8 x 32 bytes of arbitrary data per zkApp account
Expand Down Expand Up @@ -86,10 +90,6 @@ To view all of the commands and start building, run `zk --help`.

## Later

### Mina zkApp CLI

- [3rd-party fee payer for deployment txs](https://github.com/o1-labs/zkapp-cli/issues/129)

### SnarkyJS

- [Dynamic array access](https://github.com/o1-labs/snarkyjs/issues/90) — awaiting support in proof system for extended lookup tables
Expand Down

1 comment on commit a93893e

@vercel
Copy link

@vercel vercel bot commented on a93893e Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs2 – ./

docs2-git-main-minadocs.vercel.app
docs2-minadocs.vercel.app
docs.minaprotocol.com

Please sign in to comment.