diff --git a/algolia-config.json b/algolia-config.json index e5ea2f522..188edfb52 100644 --- a/algolia-config.json +++ b/algolia-config.json @@ -1,24 +1,28 @@ { "index_name": "mina", - "start_urls": ["https://docs.minaprotocol.com"], + "start_urls": [ + { + "url": "https://docs.minaprotocol.com" + } + ], "sitemap_urls": ["https://docs.minaprotocol.com/sitemap.xml"], "sitemap_alternate_links": true, "js_render": true, - "stop_urls": ["/tests"], + "js_wait": 1, + "stop_urls": ["https://docs.minaprotocol.com/node-developers"], + "selectors_exclude": ["footer"], "selectors": { "lvl0": { - "selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]", - "type": "xpath", - "global": true, - "default_value": "Documentation" + "selector": "", + "defaultValue": "Documentation" }, - "lvl1": "header h1", - "lvl2": "article h2", - "lvl3": "article h3", - "lvl4": "article h4", - "lvl5": "article h5, article td:first-child", - "lvl6": "article h6", - "text": "article p, article li, article td:last-child" + "lvl1": "header h1, article h1, main h1, h1, head > title", + "lvl2": "article h2, main h2, h2", + "lvl3": "article h3, main h3, h3", + "lvl4": "article h4, main h4, h4", + "lvl5": "article h5, main h5, h5", + "lvl6": "article h6, main h6, h6", + "text": "article p, article li, main p, main li, p, li" }, "strip_chars": " .,;:#", "custom_settings": { @@ -31,6 +35,12 @@ "url", "url_without_anchor", "type" + ], + "synonyms": [ + ["js", "javascript"], + ["ts", "typescript"], + ["es6", "ECMAScript6", "ECMAScript2015"], + ["zk", "zero-knowledge", "zero knoweldge"] ] }, "conversation_id": ["833762294"], diff --git a/docs/about-mina/consensus.mdx b/docs/about-mina/consensus.mdx index 02c8453d0..412720c38 100644 --- a/docs/about-mina/consensus.mdx +++ b/docs/about-mina/consensus.mdx @@ -1,24 +1,31 @@ --- title: Consensus +description: Mina Protocol uses a proof of stake (PoS) consensus mechanism called Ouroboros Samasika. +keywords: + - proof of stake (PoS) + - Ouroboros Samasika + - consensus mechanism + - mina consensus --- import ResponsiveVideo from '@site/src/components/common/ResponsiveVideo'; # Consensus -Mina Protocol uses a proof-of-stake consensus mechanism called **Ouroboros Samasika**. +Mina Protocol uses a proof of stake (PoS) consensus mechanism called _Ouroboros Samasika_. -Consensus is the process by which the network determines which information is retained in the blockchain. You can read about the difference between proof of stake (PoS) vs proof of work (PoW) consensus mechanisms in this blog post here. +Consensus is the process by which the network determines which information is retained in the blockchain. To learn more, see the [Proof-of-Work vs Proof-of-Stake](https://minaprotocol.com/blog/proof-of-work-vs-proof-of-stake) blog post. -Learn more about how Ouroboros Samasika works in this video: +How Ouroboros Samasika works is explained in this video: -### Decentralization properties -Based on Cardano’s PoS Ouroboros, Ouroboros Samisika is a secure PoS protocol with some strong decentralization properties: +## Decentralization properties + +Based on Cardano's PoS Ouroboros, Ouroboros Samisika is a secure PoS protocol with strong decentralization properties: - Can resolve long-range forks without relying on third parties to provide history -- **No staking minimum** — You can produce blocks and receive block rewards based on your % of the MINA staked on the network. Any user with any amount of MINA can receive these rewards. -- **No slashing** — the protocol does not need explicit slashing, since the protocol already enforces the required level of correctness. +- **No staking minimum** — You can produce blocks and receive block rewards based on your percentage of MINA staked on the network. Any user with any amount of MINA can receive these rewards. +- **No slashing** — Mina protocol does not need explicit slashing, since the protocol already enforces the required level of correctness. -Learn about how Ouroboros Samasika upholds Mina’s goals of decentralization. +See [How Ouroboros Samasika upholds Mina's goals of decentralization](https://minaprotocol.com/blog/how-ouroboros-samasika-upholds-minas-goals-of-decentralization). diff --git a/docs/about-mina/faq.mdx b/docs/about-mina/faq.mdx index b2138a7cf..22b0f9b45 100644 --- a/docs/about-mina/faq.mdx +++ b/docs/about-mina/faq.mdx @@ -1,5 +1,14 @@ --- title: Mina FAQ +description: Frequently asked questions about Mina Protocol. +keywords: + - mina faq + - mina language + - zkapp language + - 22 KB + - kimchi proof system + - mina scalability + - mina security audits --- import Subhead from "@site/src/components/common/Subhead"; @@ -13,13 +22,13 @@ Frequently Asked Questions about Mina Protocol ### What language is Mina written in? -The Mina node is written in OCaml. But you don't need to know OCaml to write smart contracts for Mina. +The Mina node is written in OCaml. You don't need to know OCaml to write smart contracts for Mina. ### What language are zkApp smart contracts written in? Mina's zero knowledge smart contracts (zkApps) are written in TypeScript. -Learn more about [how to write a zkApp](/zkapps/how-to-write-a-zkapp). +See [How to write a zkApp](/zkapps/how-to-write-a-zkapp). ### How large is the Mina Blockchain? @@ -27,21 +36,21 @@ Learn more about [how to write a zkApp](/zkapps/how-to-write-a-zkapp). ### Given Mina is only 22 KB, where are past transactions stored? -A Mina node can run with an optional flag to make it an archive node to store historic transactions. Archive nodes are useful for anyone running a service such as a block explorer. Still, this historical data is not required to verify the current consensus state of the protocol. +A Mina node can run with an optional flag to make it an archive node to store historical transactions. Archive nodes are useful for anyone running a service, such as a block explorer. Still, this historical data is not required to verify the current consensus state of the protocol. -### What zk proof system does Mina use? +### What zero knowledge (zk) proof system does Mina use? -Mina Protocol uses a custom proof system called Kimchi, which was developed by [O(1) Labs](https://o1labs.org/), and is the only blockchain offering infinite recursion. +Mina Protocol uses a custom proof system called Kimchi, developed by [O(1) Labs](https://o1labs.org/). Mina is the only blockchain offering infinite recursion. Check out the [Mina Book](https://o1-labs.github.io/proof-systems/plonk/overview.html) to learn more about Kimchi and the cryptography powering Mina Protocol. ### What can I do on the Mina network? -Any node can send and receive transactions on the Mina network. Any node can also choose to be a node operator. See [Node Operators](/node-operators). +Any node can send and receive transactions on the Mina network. Any node can also be a [node operator](/node-operators). ### What consensus algorithm does Mina use? -Mina's consensus mechanism is an implementation of Ouroboros Proof-of-Stake. Due to Mina's unique compressed blockchain, certain aspects of the algorithm have diverged from the Ouroboros papers. The version Mina uses is called Ouroboros Samisika. +Mina's consensus mechanism is an implementation of Ouroboros proof of stake. Due to Mina's unique compressed blockchain, certain aspects of the algorithm have diverged from the Ouroboros papers. The version Mina uses is called Ouroboros Samisika and achieves consensus without long-term history. #### Is there a Mina block explorer? diff --git a/docs/about-mina/index.mdx b/docs/about-mina/index.mdx index 2c49314d8..513017713 100644 --- a/docs/about-mina/index.mdx +++ b/docs/about-mina/index.mdx @@ -1,41 +1,45 @@ --- -title: Overview +title: Mina Overview +description: Mina is an L1 blockchain based on zero-knowledge proofs (ZKP) with smart contracts written in TypeScript +keywords: + - mina blockchain + - mina l1 + - 22 KB constant size blockchain + - mina network --- -# Overview +# Mina Overview -### What is Mina? +## What is Mina? -Mina is an L1 blockchain based on zero-knowledge proofs (“ZKP”) with smart contracts written in TypeScript. It is the first cryptocurrency protocol with a succinct blockchain (22KB). +Mina is an L1 blockchain based on zero-knowledge proofs (ZKP) with smart contracts written in TypeScript. It is the first cryptocurrency protocol with a succinct blockchain (22KB). -### Why Mina? +## Why Mina? -Mina Protocol uses zero-knowledge proofs to build a more ideal blockchain architecture. +Mina Protocol uses zero knowledge proofs to build a more ideal blockchain architecture. -Early blockchains, like Bitcoin and Ethereum, accumulate data over time and are currently hundreds of gigabytes in size. As time goes on, their blockchains will continue to increase in size. The entire chain history is required in order to verify the current consensus state of these networks. +Early blockchains, like Bitcoin and Ethereum, accumulate data over time and are currently hundreds of gigabytes in size. As time goes on, their blockchains will continue to increase in size. The entire chain history is required to verify the current consensus state of these networks. -With Mina, the blockchain always remains a constant size–about 22KB (the size of a few tweets). It’s possible to verify the current consensus state of the protocol using this one recursive, 22KB zero-knowledge proof. This means participants can quickly sync and verify the current consensus state of the network. +With Mina, the blockchain always remains a constant size — about 22KB (the size of a few tweets). It's possible to verify the current consensus state of the protocol using this one recursive, 22KB zero-knowledge proof. This means participants can quickly sync and verify the current consensus state of the network. -Learn more about [Mina’s unique protocol architecture](about-mina/protocol-architecture). +Learn more about Mina's unique [protocol architecture](about-mina/protocol-architecture). -### What are zero-knowledge proofs? +## What are zero-knowledge proofs? -Mina’s unique characteristics are made possible using zero-knowledge proofs. +Mina's unique characteristics are made possible using zero-knowledge proofs. -Watch this [video to learn about zero-knowledge proofs](about-mina/what-are-zero-knowledge-proofs). +Learn more in this video about [zero-knowledge proofs](about-mina/what-are-zero-knowledge-proofs). -### What are zkApps? +## What are zkApps? Mina's zero-knowledge smart contracts are referred to as zkApps. zkApps provide powerful and unique characteristics such as unlimited off-chain execution, privacy for private data inputs that are never seen by the blockchain, the ability to write smart contracts in TypeScript, and more. See [zkApps Overview](/zkapps). -### How does consensus work on Mina? +## How does consensus work on Mina? -The Mina network is secured by proof-of-stake (“PoS”) consensus called Ouroboros Samisika. +The Mina network is secured by proof of stake (PoS) consensus called Ouroboros Samisika. -Based on Cardano’s Ouroboros, Ouroboros Samisika is a PoS consensus mechanism that requires far less computing power than Bitcoin’s proof-of-work (“PoW”) protocol. +Based on Cardano's Ouroboros, Ouroboros Samisika is a PoS consensus mechanism that requires far less computing power than Bitcoin's proof of work (PoW) protocol. -With this model of consensus, you don't need expensive and energy consuming mining equipment to participate in consensus. By simply holding MINA in our wallet, we can choose to either stake it ourselves if running a block producing node, or we can delegate it to another node. - -Read more about [Mina’s consensus mechanism](./about-mina/consensus). +With this model of Mina's [consensus mechanism](/about-mina/consensus), you don't need expensive and energy-consuming mining equipment to participate in consensus. By simply holding MINA in your wallet, you can choose to stake it yourself by running a [block producer](/node-operators/block-producers) node or delegate your MINA to another node. diff --git a/docs/about-mina/protocol-architecture.mdx b/docs/about-mina/protocol-architecture.mdx index 49142ac28..217109893 100644 --- a/docs/about-mina/protocol-architecture.mdx +++ b/docs/about-mina/protocol-architecture.mdx @@ -1,6 +1,9 @@ --- -title: Protocol Architecture +title: Mina Protocol Architecture hide_title: true +description: Short video explaining how the Mina protocol works. +keywords: + - how mina protocol works --- import ResponsiveVideo from '@site/src/components/common/ResponsiveVideo'; @@ -11,11 +14,11 @@ A new version of Mina Docs is coming soon! This page will be rewritten. ::: -# Protocol Architecture +# Mina Protocol Architecture ## How Does it Work? -Check out this short video explaining how the Mina protocol works in detail: +Check out this short video explaining how the Mina protocol works: diff --git a/docs/about-mina/smart-contracts.mdx b/docs/about-mina/smart-contracts.mdx deleted file mode 100644 index 8b6a65b5e..000000000 --- a/docs/about-mina/smart-contracts.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Smart Contracts (zkApps) ---- - -#### zkApps = Dapps + Privacy + Off-Chain Data + Scalability - -As the world’s lightest blockchain, Mina enables an entirely new category of -applications called zkApps: zero-knowledge applications. zkApps are feature-wise -similar to Dapps on Ethereum, but are superior thanks to three specific -properties: - -Verify the integrity of a piece of data without disclosing what it is. Verify -correct execution of expensive computations. Significant scalability benefits. -These types of applications aren’t necessarily new - in a way both exist as -present day blockchains: ZCash as a zkApp with property 1, and Mina as a zkApp -with property 2. - -A zkApp is also significantly more efficient than a Dapp on Ethereum. In order -for the Ethereum world computer to make a commitment to its users about the -execution of a Dapp, every node and miner on the network has to run the same -computation. This is wildly inefficient. With a zkApp on Mina, the zkApp gets -executed once by its developer, after which all other nodes can just verify the -associated SNARK proof. One can make the same argument for SNARK powered Layer 2 -Dapps on Ethereum, however those Dapps are still encumbered by the limited -throughput of the main chain, whereas a zkApp on Mina benefits from the -scalability potential of the Mina blockchain thanks to its succinct nature. - -In general, a zkApp on Mina has the following workflow: - -- Identify the code to run, open source it if it isn’t already -- Use the code to deploy a SNARK circuit via a function call on Mina -- Source the data to perform the computation on -- Call the function with the relevant data -- Computation runs on chain, similar to a smart contract [ready 6-12 months - after mainnet] -- Attach the SNARK proof returned from the function to a Mina address -- Mina executes transactions based on result of the SNARK proof - -#### What else to add - -- Brief overview, including brief example use cases (non-technical aspects) -- link developers to learn how to write a zkApp or view zkApp developer docs diff --git a/docs/about-mina/what-are-zero-knowledge-proofs.mdx b/docs/about-mina/what-are-zero-knowledge-proofs.mdx index deed80b8c..0d72ce8f9 100644 --- a/docs/about-mina/what-are-zero-knowledge-proofs.mdx +++ b/docs/about-mina/what-are-zero-knowledge-proofs.mdx @@ -1,13 +1,16 @@ --- -title: What are Zero-Knowledge Proofs? +title: What are Zero Knowledge Proofs? +description: Short video explaining zero knowledge proofs. +keywords: + - zero knowledge proofs --- import ResponsiveVideo from '@site/src/components/common/ResponsiveVideo'; -# What are Zero-Knowledge Proofs? +# What are Zero Knowledge Proofs? -Zero-knowledge proofs keep Mina's blockchain light and your personal data private. +Zero knowledge proofs keep Mina's blockchain light and your personal data private. -In this video, Brandon from O(1) Labs explains what zero-knowledge proofs are by comparing them to the game of "Where's Waldo?". By the end of this video, you know what zero-knowledge proofs are, how they work, and their importance to Mina and the greater crypto community. +In this video, Brandon from O(1) Labs explains what zero knowledge proofs are by comparing them to the game of "Where's Waldo?". Learn what zero knowledge proofs are, how they work, and their importance to Mina and the greater crypto community. diff --git a/docs/glossary.mdx b/docs/glossary.mdx index d591a6e85..73d3ef6ff 100644 --- a/docs/glossary.mdx +++ b/docs/glossary.mdx @@ -13,8 +13,8 @@ keywords: # Glossary -[A](#a) [B](#b) [C](#c) [D](#d) [E](#e) [F](#f) [I](#i) [J](#j) [K](#k) [L](#l) [M](#m) [N](#n) [O](#o) -[P](#p) [Q](#q) [R](#r) [S](#s) [T](#t) [U](#u) [V](#v) [Z](#z) +[A](#a) [B](#b) [C](#c) [D](#d) [E](#e) [F](#f) G H [I](#i) J [K](#k) [L](#l) [M](#m) [N](#n) [O](#o) +[P](#p) Q [R](#r) [S](#s) [T](#t) [U](#u) [V](#v) W X Y [Z](#z) Are you looking for a zero knowledge or Mina term that isn't here yet? To let us know, please [create an issue](https://github.com/o1-labs/docs2/issues) or click **EDIT THIS PAGE** to submit a PR. @@ -82,7 +82,7 @@ Generating a SNARK for a computation output can be thought of as compressing tha ### consensus -An algorithm or set of rules that Mina nodes all agree upon when deciding to update the state of the network. Rules can include what data a new block can contain and how nodes are selected and rewarded for adding a block. Mina implements the [Ouroboros Samisika](/glossary#ouroboros-samisika) consensus mechanism. +A process through which all the peers of a blockchain network reach a common agreement about the present state of the distributed ledger. A consensus algorithm or set of rules that Mina nodes all agree upon when deciding to update the state of the network. Rules can include what data a new block can contain and how nodes are selected and rewarded for adding a block. Mina implements the [Ouroboros Samisika](/glossary#ouroboros-samisika) consensus mechanism. ### consensus node @@ -98,6 +98,10 @@ A digital asset or currency that uses cryptographic primitives to secure financi The Mina daemon is a background process that implements the Mina protocol and runs on a node locally so a local client or wallet can talk to the Mina network. For example, when a CLI is used to issue a command to send a transaction, this request is made to the Mina daemon, which then broadcasts it to the peer-to-peer network. The daemon also listens for events like new blocks and relays this to the client by using a [pub-sub](#pub-sub) model. +### DAO + +A decentralized autonomous organization (DAO) operates based on rules that are encoded on a blockchain and executed through smart contracts. DAOs are an organizational structure built with blockchain technology. + ### delegating Because staking MINA requires nodes to be online, some nodes delegate their MINA to another node that runs a staking service. This process is called delegating a stake. The service provider or staking pool operator can charge a fee that is deducted any time the delegator gets selected to be a block producer. @@ -112,6 +116,14 @@ A digital system for recording the transaction of assets in which the transactio ## E +## elliptic curves + +Equations with a specific template: _y^2 = x^3 + ax^ + b_: [secp256k1](/glossary#secp256k1), + +### elliptic-curve cryptography (ECC) + +An approach to public key cryptography based on the algebraic structure of elliptic curves over finite fields. ECC is the basis of how Ethereum and other cryptocurrencies use private keys and digital signatures. + ### epoch A unit of time equal to 7140 slots at Mainnet. An epoch is divided into [slots](#slot) of 3minutes each. @@ -130,6 +142,10 @@ Also referred to as a [block](#block), an external transition is generated exter ## F +## fee payer account + +A developer account that is funded and can always pay fees immediately. When you configure a zkApp, you can choose to use a stored account or create a new fee payer account. + ### field element The basic unit of data in zero knowledge proof programming. Each field element can store a number up to almost 256 bits in size. You can think of a field element as a uint256 in Solidity. For the cryptography inclined, the exact max value that a field can store is 28,948,022,309,329,048,855,892,746,252,171,976,963,363,056,481,941,560,715,954,676,764,349,967,630,336. @@ -142,6 +158,8 @@ A consensus constant `k` is the point at which chain [reorganizations](#reorgani A Mina node that is able to verify the state of the network trustlessly. In Mina, every node is a full node since all nodes can receive and verify zk-SNARKs. +## I + ### internal transition A [transition](#transition) that is produced locally, for example, by a block producer. The generated transition is applied locally and added to the [transition frontier](#transition-frontier) before being broadcast to peers. @@ -158,7 +176,7 @@ A combination of a [private key](#private-key) and [public key](#public-key). Ke ### Kimchi -The proof system for Mina, Kimchi is the main machinery that generates the recursive proofs that keep the Mina blockchain small (about 22 KB). Kimchi is a zero-knowledge proof system that's a variant of [PLONK](/glossary#plonk). +The proof system for Mina, Kimchi is the main machinery that generates the recursive proofs that keep the Mina blockchain small (about 22 KB). Kimchi, a zero-knowledge proof system that's a variant of [PLONK](/glossary#plonk), features a polynomial commitment scheme that supports verifiable computation using traditional Turing machine-based instruction sets. ## L @@ -214,6 +232,14 @@ An incrementing number attached to a transaction used to prevent a replay of a t ## O +### off-chain + +A transfer of value or data, including transactions, that occurs outside a given blockchain network. These transfers do not need blockchain network confirmation, which speeds up the transaction process and reduces lag time. + +### on-chain + +A transfer of value or data, including transactions, that exist on and have been verified to a blockchain network. All relevant information is time-stamped and stored on the public ledger. On-chain transactions are recorded on the blockchain and need network confirmation before they are completed. + ### Ouroboros Samisika Mina builds on this provably secure proof of stake (PoS) protocol that combines the best features of each iteration of Ouroboros to deliver a PoS consensus mechanism that can resolve long-range forks without requiring history or risking centralization by relying on trusted third parties to provide fork information. @@ -228,13 +254,17 @@ Networking systems that rely on peer nodes to distribute information amongst eac Mina's inductive zk-SNARK composition system. See [Pickles](https://o1-labs.github.io/proof-systems/specs/pickles.html). +### Pickles SNARK + +A proof system and associated toolkit that is the first deployed SNARK capable of recursive composition with no trusted setup. Pickles serves as the basis for developers to build private, scalable smart contracts on Mina. [Meet Pickles SNARK: Enabling Smart Contracts on Mina Protocol](https://medium.com/minaprotocol/meet-pickles-snark-enabling-smart-contract-on-coda-protocol-7ede3b54c250). + ### PLONK Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of Knowledge (PLONK) is general-purpose zero knowledge proof scheme. -### Pickles SNARK +### polynomial commitment -A proof system and associated toolkit that is the first deployed SNARK capable of recursive composition with no trusted setup. Pickles serves as the basis for developers to build private, scalable smart contracts on Mina. [Meet Pickles SNARK: Enabling Smart Contracts on Mina Protocol](https://medium.com/minaprotocol/meet-pickles-snark-enabling-smart-contract-on-coda-protocol-7ede3b54c250). +A commitment scheme that allows a committer to commit to a polynomial with a short string that can be used by a verifier to confirm claimed evaluations of the committed polynomial. ### precomputed block @@ -252,9 +282,17 @@ The state of the network that comprises the previous protocol state hash to link The hash of hashes of the previous state and [protocol state](#protocol-state) body. Acts as a unique identifier for a block. +### proof of liabilities (PoL) + +A cryptographic primitive to prove the size of funds a bank, or centralized exchange (CEX), owes to its customers in a decentralized manner and can be used for solvency audits with better privacy guarantees. + ### proof of stake (PoS) -The Mina consensus algorithm that allows nodes to agree on the state of the network. PoS allows nodes to [stake](node-operators/staking-and-snarking) MINA on the network to increase their chance of being selected as the next block producer. +The Mina consensus algorithm that allows nodes to agree on the state of the network. PoS allows nodes to [stake](node-operators/staking-and-snarking) MINA on the network to increase their chance of being selected as the next block producer. The winning validators are compensated with a percentage yield of the crypto they have staked as an incentive for engaging in this process. See [Proof-of-Work vs Proof-of-Stake](https://minaprotocol.com/blog/proof-of-work-vs-proof-of-stake). + +### proof of work (PoW) + +The original consensus process used by Bitcoin, the first cryptocurrency. PoW achieves the decentralized consensus needed to add new blocks to a blockchain by using machines to compete against one another by guessing the answer to math problems that have no feasible faster solution. Computational power is a requirement for the PoW protocol success and assumes that those contributing more resources (energy, supercomputers, and infrastructure) to a problem are less likely to want to destroy the protocol. As an incentive to participate in this consensus process, miners are rewarded with tokens. ### prover function @@ -292,6 +330,10 @@ An [(RPC)] (https://en.wikipedia.org/wiki/Remote_procedure_call) is used to comm A data structure that allows decoupling the production of transaction SNARKs from block producers to [SNARK workers](#snark-worker). See [Scan State](/node-operators/scan-state). +### secp256k1 + +The elliptic curve using this equation _y²=x³+7, a=0 b=7_, constructed in a special non-random way to allow for especially efficient computation. secp256k1 can have a key size of up to 256 bits. All points on this curve are valid public keys. + ### signature Short for digital signature, a way to establish authenticity or ownership of digitally signed messages. @@ -402,4 +444,6 @@ Zero knowledge apps (zkApps) are Mina Protocol's smart contracts powered by zero A type of zero-knowledge proof. zk-SNARK is the acronym for zero knowledge succinct non-interactive argument of knowledge. Specific properties of interest in Mina's implementation of SNARKs are succinctness and non-interactivity that allow for any node to quickly verify the state of the network. -#### [Back to top](/glossary) +[A](#a) [B](#b) [C](#c) [D](#d) [E](#e) [F](#f) G H [I](#i) J [K](#k) [L](#l) [M](#m) [N](#n) [O](#o) +[P](#p) Q [R](#r) [S](#s) [T](#t) [U](#u) [V](#v) W X Y [Z](#z) + diff --git a/docs/image-example.mdx b/docs/image-example.mdx deleted file mode 100644 index fbb538880..000000000 --- a/docs/image-example.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Image Example ---- - -# Image Example - -## Docs reference to link images: - -https://docusaurus.io/docs/markdown-features/assets#images - -## Display images with Markdown syntax: - -![Docusaurus](/img/homepage/zkapp_developers.png) - -## Display images with JavaScript: - - diff --git a/docs/mina-faq.mdx b/docs/mina-faq.mdx deleted file mode 100644 index bb757756c..000000000 --- a/docs/mina-faq.mdx +++ /dev/null @@ -1,85 +0,0 @@ -# FAQ - - - -## General Questions - - - - -### Why did you develop a new protocol? - -The reason for developing a new protocol instead of offering services to other blockchains is because adding SNARKs after the fact to a Layer 1 project is not trivial. Even basic operations need to be optimized for performance inside a SNARK, and existing implementations are not able to be retrofit as such. If we look at hashing functions for example, SHA256 (used by Bitcoin) or Keccak (used by Ethereum) are extremely expensive inside a SNARK circuit, but Poseidon (what Mina uses) is optimized for performance. This and many other technical considerations make it infeasible to easily add recursive SNARKs to existing Layer 1 blockchains, without entirely overhauling the base protocol. - -#### How does Mina verify the current state of the chain without having historical data? How do you audit a transaction if you only keep a proof of the blockchain? - -The average user does not need to know the entire transaction history. For -example, when you make a purchase using a dollar, you also don't need to know -where that dollar came from and how it was spent before arriving in your wallet. -Other blockchains depend on the transaction history to verify that the current -state is valid. Mina is using zk-SNARKs to prove that (see -[this video](https://www.youtube.com/watch?v=eWVGATxEB6M) where co-founder Izaak -Meckler explains Mina's recursive use of zk-SNARKs). This enables Mina to become -the world's lightest blockchain and to always be accessible for all. - -For cases where a user wants to prove the inclusion of past transactions, Mina -has a feature called the receipt chain. Each account has its own receipt chain, -represented in the current state by a hash. When a user sends a transaction from -an account, that transaction modifies the receipt chain of the account, to be -the hash of the previous receipt chain, and the new transaction (a merkle list). -This allows users to prove a particular transaction was sent from their account. - -For programs, Mina uses a different programming paradigm than other chains - -instead of being able to reference past history, you can only reference the -current state. This is akin to a filesystem that allows writing, deleting, and -overwriting data, rather than the “append only” filesystem seen in the usual -blockchain. This is intentional, so that Mina will always be lightweight, and -sustainable - once the proof is available to stand in for the history, storing -the history is more for archival or reference purposes, rather than security or -necessary use. - -The programming paradigm in Mina will be designed to reflect this - right now -Mina has minimal data per account. Programs storing more data will have to pay -some amount for that data, likely when added with something like state rent. - -Clients that do seek to have the full archival history can operate as archive -nodes, to store the full history as well. However, because unlike other -blockchains the full history isn’t necessary for any actions that can be -performed on chain, these are more for data analysis purposes than anything -else. - - -#### Does Mina support shielded transactions, like in Zcash? - -No, Mina does not natively implement privacy features at the moment. However, -privacy is a key consideration for cryptocurrencies, and is also on the -development roadmap. - -#### Can I run the Mina daemon as a service - -See here for information about using launchd or systemd with Mina. - -## SNARKs and Snark Workers - -#### Is generating SNARKs similar to Proof-of-Work (PoW) mining? - -No, they are different in several ways: - -- SNARK work is deterministic, while PoW mining requires randomly calculating - hashes to try and solve a puzzle. There is no luck element in SNARK work — if - a snark worker wants to generate a SNARK of a transaction, they only need to - generate the proof once. This means SNARK work is much less expensive and - environmentally wasteful, as the compute is all spent towards a productive - goal. -- There is no difficulty increase for SNARK work, as there is with PoW mining. - In fact, as SNARK constructions, and proof generation times improve, the - difficulty may actually decrease. -- SNARK work is not directly involved in consensus. Snark workers play no role - in determining the next state of the blockchain. Their role is to simply - generate SNARKs of transactions observed in the network -- As a snark worker, there is no requirement for uptime. PoW miners need to run - their rigs non-stop to ensure they don't miss out on a potential block. Snark - workers can come online and offline as they please — it is more like Uber, - where there will always be work to be done, and nobody needs to say ahead of - time when they want to work. - diff --git a/docs/node-developers/graphql-api.mdx b/docs/node-developers/graphql-api.mdx index 7282141d0..5c74aa637 100644 --- a/docs/node-developers/graphql-api.mdx +++ b/docs/node-developers/graphql-api.mdx @@ -19,17 +19,21 @@ A new version of Mina Docs is coming soon! This page will be rewritten. ::: -The Mina daemon exposes a [GraphQL API](https://graphql.org/) used to request information from and submit commands to a running node. By default, an HTTP server runs on port `3085`, though this may be configured by passing the `-rest-port` flag to the daemon startup command. +The Mina daemon exposes a [GraphQL API](https://graphql.org/) used to request information from and submit commands to a running node. -To use the GraphQL API, connect your GraphQL client to `http://localhost:3085/graphql` or open in your browser to utilize the [GraphiQL IDE](https://github.com/graphql/graphiql). By default, for security, only connections from `localhost` are permitted. To listen on all interfaces, add the `-insecure-rest-server` flag to the daemon startup command. +To use the GraphQL API, connect your GraphQL client to `http://localhost:3085/graphql` or open in your browser to use the [GraphiQL IDE](https://github.com/graphql/graphiql). -In addition to information about the running node, the GraphQL API can return data about the network's latest blocks. However, as the blockchain's historical state is not persisted in Mina, only blocks in the node's transition frontier are returned, i.e., the last `k` blocks. For other historical data, use the archive node that is designed to retain and retrieve historical data. +- By default, an HTTP server runs on port `3085`. You can configure a different port, use the `-rest-port` flag with the daemon startup command. -The full Mina GraphQL schema is available [here](https://github.com/MinaProtocol/mina/blob/develop/graphql_schema.json). +- The default security permits only connections from `localhost`. To listen on all interfaces, add the `-insecure-rest-server` flag to the daemon startup command. + +In addition to information about the running node, the GraphQL API can return data about the network's latest blocks. However, as the blockchain's historical state is not persisted in Mina, only blocks in the node's transition frontier are returned, i.e., the last `k` blocks. For other historical data, use the [Archive Node](/node-operators/archive-node) that is designed to retain and retrieve historical data. + +The full Mina GraphQL schema is available [https://github.com/MinaProtocol/mina/blob/develop/graphql_schema.json](https://github.com/MinaProtocol/mina/blob/develop/graphql_schema.json). ### Queries -The Mina GraphQL API has a number of [queries](https://docs.minaprotocol.com/node-operators/querying-data) to extract data from a running node. [GraphQL queries](https://graphql.org/learn/queries/) allow specifying the data to be returned in the response. For example to get the latest block and creator information known to the daemon: +The Mina GraphQL API has a number of [queries](/node-operators/querying-data) to extract data from a running node. [GraphQL queries](https://graphql.org/learn/queries/) allow specifying the data to be returned in the response. For example, to get the latest block and creator information known to the daemon: ``` query { @@ -49,7 +53,7 @@ query { } ``` -The following query requests all pending transactions in the [transaction pool](#) together with their fees. This query may be used to generate an estimate of a suggested fee for a transaction: +The following query requests all pending transactions in the transaction pool together with their fees. This query can be used to generate an estimate of a suggested fee for a transaction: ``` query { @@ -88,15 +92,11 @@ curl -d '{"query": "{ }"}' -H 'Content-Type: application/json' http://localhost:3085/graphql ``` -### Mutations: +### Mutations GraphQL mutations modify the running node in some way. For example, mutations may be used to send a payment, create a new account, or to add additional peers. -:::tip - -Consult the [GraphQL schema](https://docs.minaprotocol.com/graphql-docs/mutation.doc.html) for all available mutations. - -::: +Consult the GraphQL schema for all available mutations. Adding a new peer: @@ -110,7 +110,7 @@ mutation { } ``` -Update a snark worker to use a fee of 0.1 mina: +Update a SNARK worker to use a fee of 0.1 MINA: ``` mutation { @@ -118,9 +118,9 @@ mutation { } ``` -### Subscriptions: +### Subscriptions -A GraphQL [subscription](https://docs.minaprotocol.com/graphql-docs/subscription.doc.html) allows a GraphQL client to have data pushed to it when an event occurs. In Mina, there are subscriptions for: +A GraphQL subscription allows a GraphQL client to have data pushed to it when an event occurs. In Mina, there are subscriptions for: - _newSyncUpdate_ - occurs when the sync status of the node changes. - _newBlock_ - occurs when a new block is received. @@ -143,14 +143,14 @@ subscription { } ``` -The new block subscription may also be limited to only return new blocks created by a defined public key with the `publicKey` argument. +The new block subscription can also be limited to return only new blocks created by a defined public key with the `publicKey` argument. ### GraphQL Public Proxy -While exposing the GraphQL API to the internet is not recommended, an implementation of a [GraphQL proxy](https://github.com/MinaProtocol/mina/tree/master/automation/services/graphql-public-proxy) is available that removes the queries that pose a threat but still allows querying of the node's data from a public endpoint. +While exposing the GraphQL API to the internet is not recommended, an implementation of a [GraphQL proxy](https://github.com/MinaProtocol/mina/tree/master/automation/services/graphql-public-proxy) is available that removes the queries that pose a threat, but still allows querying of the node's data from a public endpoint. ### Resources -- [5-minute introduction video on Mina GraphQL API](http://bit.ly/GraphQLAPIin5) +- [5-minute introduction video on Mina GraphQL API](http://bit.ly/GraphQLAPIin5) Coda - [First steps with the Mina GraphQL API](https://garethtdavies.com/crypto/first-steps-with-coda-graphql-api.html) - [Introduction to GraphQL](https://graphql.org/learn/) diff --git a/docs/node-operators/archive-node.mdx b/docs/node-operators/archive-node.mdx index 793761aa7..930d36be6 100644 --- a/docs/node-operators/archive-node.mdx +++ b/docs/node-operators/archive-node.mdx @@ -106,6 +106,143 @@ To run a local archive node to run it in the foreground for testing: To connect to an archive process on another machine, specify a hostname with `localhost:3086`. +## Set up the archive node using Docker + +To get started with installing and running the archive node using Docker, follow the steps below. + +1. Install Docker on your machine. For more information, see [Docker](https://docs.docker.com/get-docker/). + +2. Pull the archive node image from Docker Hub. + + ```sh + docker pull minaprotocol/mina-archive:1.3.0-9b0369c-bullseye + ``` + +3. Pull and install the postgres image from Docker Hub. + + ```sh + docker pull postgres + ``` + +4. Start the postgres container and expose it's networking to other containers. + + ```sh + docker run --name postgres -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d postgres + ``` + +5. Create a local postgres database called `archive`. + + ```sh + docker exec -it postgres createdb -U postgres archive + ``` + +6. Load the mina archive schema into the archive database. + + ```sh + curl -Ls https://raw.githubusercontent.com/MinaProtocol/mina/master/src/app/archive/create_schema.sql | docker exec -i postgres psql -U postgres -d archive + ``` + +7. Create a local directory to store the archive node data. + + ```sh + mkdir -p /tmp/archive + ``` + +8. Start the archive node. + + ```sh + docker run \ + --name archive \ + -p 3086:3086 \ + -v /tmp/archive:/data \ + minaprotocol/mina-archive:1.3.0-9b0369c-bullseye \ + mina-archive run \ + --postgres-uri postgres://postgres:postgres@postgres:5432/archive \ + --server-port 3086 + + ``` + +9. Start the mina daemon and connect it to the archive process that you started on port 3086: + + ``` + mina daemon \ + ..... + --archive-address 3086\ + ``` + +## Set up the archive node using Docker Compose + +Docker Compose is a tool for defining and running multi-container Docker applications. +With Compose, you use a YAML file to configure your application's services. Then, with a single command, you create and start all the services from your configuration. + +To run the archive node using Docker Compose: + +1. Install Docker on your machine. For more information, see [Docker](https://docs.docker.com/get-docker/). + +2. Install Docker Compose on your machine. For more information, see [Docker Compose](https://docs.docker.com/compose/install/). + +3. Pull the archive node image from Docker Hub. + + ```sh + docker pull minaprotocol/mina-archive:1.3.0-9b0369c-bullseye + ``` + +4. Pull and install the postgres image from Docker Hub. + + ```sh + docker pull postgres + ``` + +5. Create a local directory to store the archive node data. + + ```sh + mkdir -p /tmp/archive + ``` + +6. Create a `docker-compose.yml` file with the following contents: + + ```yml + version: '3.8' + services: + postgres: + image: postgres + environment: + POSTGRES_PASSWORD: postgres + volumes: + - './postgres-data:/var/lib/postgresql/data' + ports: + - '5432:5432' + archive: + image: 'minaprotocol/mina-archive:1.3.0-9b0369c-bullseye' + command: >- + mina-archive run --postgres-uri + postgres://postgres:postgres@postgres:5432/archive --server-port 3086 + volumes: + - '/tmp/archive:/data' + ports: + - '3086:3086' + depends_on: + - postgres + ``` + +7. Start the archive node. + + ```sh + # If you are running Docker Compose V1: + docker-compose up + + # If you are running Docker Compose V2: + docker compose up + ``` + +8. Start the mina daemon and connect it to the archive process that you started on port 3086: + + ``` + mina daemon \ + ..... + --archive-address 3086\ + ``` + ## Using the Archive Node Take a look at the tables in the database. diff --git a/docs/node-operators/connecting-to-devnet.mdx b/docs/node-operators/connecting-to-devnet.mdx index 756d2c7fa..d8c5a226e 100644 --- a/docs/node-operators/connecting-to-devnet.mdx +++ b/docs/node-operators/connecting-to-devnet.mdx @@ -91,7 +91,7 @@ EXTRA_FLAGS=" --block-producer-key " PEER_LIST_URL=https://storage.googleapis.com/seed-lists/devnet_seeds.txt ``` -- Replace with the full path to your block producer private key. For example, `/home/ubuntu/keys/my-wallet`. +Replace `` with the full path to your block producer private key. For example, `/home/ubuntu/keys/my-wallet`. If you do not want to produce blocks, then provide only the `PEER_LIST_URL`. @@ -111,18 +111,18 @@ daemon \ Follow the logs: - ```sh - docker logs -f mina - ``` +```sh +docker logs -f mina +``` If the node crashes, save the log output to a file: - ```sh - docker logs mina > mina-log.txt - ``` +```sh +docker logs mina > mina-log.txt +``` Monitor connectivity to the network: - ```sh - docker exec -it mina mina client status - ``` +```sh +docker exec -it mina mina client status +``` diff --git a/docs/node-operators/connecting-to-the-network.mdx b/docs/node-operators/connecting-to-the-network.mdx index 18e84b144..6434acd70 100644 --- a/docs/node-operators/connecting-to-the-network.mdx +++ b/docs/node-operators/connecting-to-the-network.mdx @@ -73,21 +73,22 @@ Auto-restart flows are in place to ensure your nodes perform optimally. 1. Start a standalone mina node to make sure everything works. - To start a Mina node instance and connect to the live network: + To start a Mina node instance and connect to the live network: - ```sh - mina daemon --peer-list-url https://storage.googleapis.com/seed-lists/mainnet_seeds.txt - ``` + ```sh + mina daemon --peer-list-url https://storage.googleapis.com/seed-lists/mainnet_seeds.txt + ``` - The `--peer-list` argument specifies the the source file of seed peer addresses for the initial peer to connect to on the network. Mina is a [peer-to-peer](/glossary#peer-to-peer) protocol, so there is no dependence on a single centralized server. + The `--peer-list` argument specifies the the source file of seed peer addresses for the initial peer to connect to on the network. Mina is a [peer-to-peer](/glossary#peer-to-peer) protocol, so there is no dependence on a single centralized server. - If you have a key with MINA stake and want to produce blocks: - - ```sh - mina daemon --peer-list-url https://storage.googleapis.com/seed-lists/mainnet_seeds.txt --block-producer-key ~/keys/my-wallet - ``` - - where `~/keys/my-wallet` is the path to your private key, if not the default. + If you have a key with MINA stake and want to produce blocks: + + ```sh + mina daemon --peer-list-url https://storage.googleapis.com/seed-lists/mainnet_seeds.txt \ + --block-producer-key ~/keys/my-wallet + ``` + + where `~/keys/my-wallet` is the path to your private key, if not the default. For help solving common issues when first running a node, see Node Operators [Troubleshooting](/node-operators/troubleshooting). @@ -108,36 +109,36 @@ To produce blocks or otherwise customize the configuration for the mina daemon: 1. Create the `~/.mina-env` file. 1. To produce blocks, add the required configuration: - ``` - MINA_PRIVKEY_PASS="My_V3ry_S3cure_Password" - LOG_LEVEL=Info - FILE_LOG_LEVEL=Debug - EXTRA_FLAGS=" --block-producer-key " - ``` + ``` + MINA_PRIVKEY_PASS="My_V3ry_S3cure_Password" + LOG_LEVEL=Info + FILE_LOG_LEVEL=Debug + EXTRA_FLAGS=" --block-producer-key " + ``` - Replace with the full path to your block producer private key. For example, `/home/ubuntu/keys/my-wallet`. + Replace `` with the full path to your block producer private key. For example, `/home/ubuntu/keys/my-wallet`. - If you do not want to produce blocks then you can keep `~/.mina-env` empty for now. + If you do not want to produce blocks then you can keep `~/.mina-env` empty for now. 1. To change how mina is configured, specify flags to the mina daemon process with space-separated arguments between the quotes in `EXTRA_FLAGS=""`. - You can change the default values with `EXTRA_FLAGS`: + You can change the default values with `EXTRA_FLAGS`: - - External port 8302 - - Change with `-external-port` - - Mainnet package [https://storage.googleapis.com/seed-lists/mainnet_seeds.txt](https://storage.googleapis.com/seed-lists/mainnet_seeds.txt) - - Change with `--peer-list-url` + - External port 8302 + - Change with `-external-port` + - Mainnet package [https://storage.googleapis.com/seed-lists/mainnet_seeds.txt](https://storage.googleapis.com/seed-lists/mainnet_seeds.txt) + - Change with `--peer-list-url` 1. After your `.mina-env` file is ready, start a Mina node instance and connect to the live network: - ```sh - systemctl --user daemon-reload - systemctl --user start mina - systemctl --user enable mina - sudo loginctl enable-linger - ``` + ```sh + systemctl --user daemon-reload + systemctl --user start mina + systemctl --user enable mina + sudo loginctl enable-linger + ``` - These commands allow the node to continue running after you log out and restart automatically when the machine reboots. + These commands allow the node to continue running after you log out and restart automatically when the machine reboots. ## Check your connectivity @@ -145,56 +146,56 @@ Monitor the mina process that's running in the background and auto-restarting. Check if `mina` had any trouble getting started: - ```sh - systemctl --user status mina - ``` +```sh +systemctl --user status mina +``` Stop mina gracefully and stop automatically restarting the service: - ```sh - systemctl --user stop mina - ``` +```sh +systemctl --user stop mina +``` Manually restart the mina process: - ```sh - systemctl --user restart mina - ``` +```sh +systemctl --user restart mina +``` Look at logs that show the last 1000 lines, and follow from there: - ```sh - journalctl --user -u mina -n 1000 -f - ``` +```sh +journalctl --user -u mina -n 1000 -f +``` In some cases, you might need run the following command to view the logs: - ```sh - journalctl --user-unit mina -n 1000 -f - ``` +```sh +journalctl --user-unit mina -n 1000 -f +``` ### Docker When running your daemon using Docker, first ensure that your private key has the correct permissions. - ```sh - cd ~ - chmod 700 ~/keys - chmod 600 ~/keys/my-wallet - mkdir ~/.mina-config - ``` +```sh +cd ~ +chmod 700 ~/keys +chmod 600 ~/keys/my-wallet +mkdir ~/.mina-config +``` To produce blocks or otherwise customize the configuration for the mina daemon, create a `~/.mina-env` files with the following: - ```sh - export MINA_PRIVKEY_PASS="My_V3ry_S3cure_Password" - LOG_LEVEL=Info - FILE_LOG_LEVEL=Debug - EXTRA_FLAGS=" --block-producer-key " - PEER_LIST_URL=https://storage.googleapis.com/seed-lists/mainnet_seeds.txt - ``` +```sh +export MINA_PRIVKEY_PASS="My_V3ry_S3cure_Password" +LOG_LEVEL=Info +FILE_LOG_LEVEL=Debug +EXTRA_FLAGS=" --block-producer-key " +PEER_LIST_URL=https://storage.googleapis.com/seed-lists/mainnet_seeds.txt +``` - Replace with the full path to your block producer private key. For example, `/home/ubuntu/keys/my-wallet`. +Replace `` with the full path to your block producer private key. For example, `/home/ubuntu/keys/my-wallet`. If you do not want to produce blocks, then provide only the `PEER_LIST_URL`. @@ -215,23 +216,23 @@ daemon Follow the logs: - ```sh - docker logs -f mina - ``` +```sh +docker logs -f mina +``` If the node crashes, save the log output to a file: - ```sh - docker logs mina > mina-log.txt - ``` +```sh +docker logs mina > mina-log.txt +``` - Post the output to the [#mentor-nodes](https://discord.com/channels/484437221055922177/746316198806814760) channel on Mina Protocol Discord or attach the full `~/.mina-config/mina.log` to a GitHub issue and link the issue in Discord. +Post the output to the [#mentor-nodes](https://discord.com/channels/484437221055922177/746316198806814760) channel on Mina Protocol Discord or attach the full `~/.mina-config/mina.log` to a GitHub issue and link the issue in Discord. Monitor connectivity to the network: - ```sh - docker exec -it mina mina client status - ``` +```sh +docker exec -it mina mina client status +``` At least 10 peers are expected. Watch the block height and the max observed block height climb. @@ -247,9 +248,9 @@ Monitor the mina client status in a different terminal window. Now that a node is started and running the Mina daemon, run: - ```sh - mina client status - ``` +```sh +mina client status +``` When first starting up a node, it can take up to a minute before `mina client status` connects to the daemon. If you see `Error: daemon not running. See mina daemon`, just a wait a bit and try again. diff --git a/docs/node-operators/foundation-delegation-program.mdx b/docs/node-operators/foundation-delegation-program.mdx index 82424a177..7c664ec37 100644 --- a/docs/node-operators/foundation-delegation-program.mdx +++ b/docs/node-operators/foundation-delegation-program.mdx @@ -28,7 +28,7 @@ The current sidecar tracking system is being phased out to be replaced by the SN - [Instructions for the sidecar tracking system](/node-operators/bp-sidecar) - [Instructions for the SNARK-work-based uptime system](/node-operators/uptime-tracking-system) -Please follow the latest updates and post questions in the [the [#delegation-program](https://discord.com/channels/484437221055922177/808895957978447882) channel on Mina Protocol Discord. +Please follow the latest updates and post questions in the [#delegation-program](https://discord.com/channels/484437221055922177/808895957978447882) channel on Mina Protocol Discord. ::: diff --git a/docs/node-operators/generating-a-keypair.mdx b/docs/node-operators/generating-a-keypair.mdx index e0a12e164..2aac9801b 100644 --- a/docs/node-operators/generating-a-keypair.mdx +++ b/docs/node-operators/generating-a-keypair.mdx @@ -124,7 +124,7 @@ Never give out your private key and make sure they are stored safely. If you los 4. Finally, ensure the permissions are set properly for the private key file, this prevents unwanted processes from accessing it. ``` -chmod 600 ~/keys/my-wallet +chmod 600 $(pwd)/keys/my-wallet ``` ## Validate your private key diff --git a/docs/zkapps/how-to-deploy-a-zkapp.mdx b/docs/zkapps/how-to-deploy-a-zkapp.mdx index eee0551b8..1ead5af27 100644 --- a/docs/zkapps/how-to-deploy-a-zkapp.mdx +++ b/docs/zkapps/how-to-deploy-a-zkapp.mdx @@ -29,25 +29,16 @@ following command: zk config ``` -When prompted, specify a name (can be anything), URL to deploy to, and fee (in -MINA) to be used when sending your deploy transaction. The URL is the Mina GraphQL API -that receives your deploy transaction and broadcasts it to the Mina network. -Note that this URL is significant because it also determines which network you're -be deploying to (for example, QANet, Testnet, or Mainnet). +When prompted, specify a name (can be anything), URL to deploy to, fee (in +MINA) to be used when sending your deploy transaction, and the fee payer account. -To deploy a zkApp to the Berkeley Testnet, use the following values: - -- **Name**: `berkeley` -- **URL**: `https://proxy.berkeley.minaexplorer.com/graphql` or `https://berkeley.minascan.io/graphql` -- **Fee**: `0.1` +For more details, see [Deploy alias](/zkapps/tutorials/deploying-to-a-network#deploy-alias) in Tutorial 3: Deploy to a Live Network. :::tip If your project contains multiple smart contracts (for example, `Foo` and `Bar`) that you intend to deploy to the same network, a best practice is to follow a naming convention such as `berkeley-foo` and `berkeley-bar` when naming your deploy aliases. You can change these alias names at anytime in `config.json`. ::: -
- You see the following output: ```sh diff --git a/docs/zkapps/how-to-test-a-zkapp.mdx b/docs/zkapps/how-to-test-a-zkapp.mdx index efc102052..fbd5aa454 100644 --- a/docs/zkapps/how-to-test-a-zkapp.mdx +++ b/docs/zkapps/how-to-test-a-zkapp.mdx @@ -8,6 +8,7 @@ keywords: - Smart contract - Jest - Local blockchain + - Docker test --- :::info @@ -18,10 +19,23 @@ zkApp programmability is not yet available on the Mina Mainnet. You can get star # How to Test a zkApp -Writing automated tests for your smart contract is essential to ensure your code is well tested during development. All projects created using the Mina zkApp CLI include the [Jest](https://jestjs.io/) JavaScript testing framework. Although you can use any testing framework, the instructions in this document are supported for Jest. +Writing automated tests for your smart contract is essential to ensure your code is well-tested during development. + +## Test zkApps on a lightweight Mina local network + +A Docker image for Mina local networks provides a simple and efficient way to deploy and run lightweight Mina blockchain networks for testing zkApps. The `o1labs/mina-local-network` Docker image provides: + +- Genesis ledger with pre-funded accounts +- Accounts manager service +- Additional port served by reverse proxy to pass requests to the Mina daemon GraphQL endpoint so zkApps work without additional configuration +- Single commands to launch a single node or multi node network + +Pull the [o1labs/mina-local-network](https://hub.docker.com/r/o1labs/mina-local-network) image from Docker Hub. ## Writing tests for your smart contract +All projects created using the Mina zkApp CLI include the [Jest](https://jestjs.io/) JavaScript testing framework. Although you can use any testing framework, the instructions in this document are supported for Jest. + Use the Mina zkApp CLI to create tests for your smart contract. To scaffold a TypeScript file with a corresponding test file, run: diff --git a/docs/zkapps/how-to-write-a-zkapp.mdx b/docs/zkapps/how-to-write-a-zkapp.mdx index fe4c73865..914cd27ef 100644 --- a/docs/zkapps/how-to-write-a-zkapp.mdx +++ b/docs/zkapps/how-to-write-a-zkapp.mdx @@ -86,21 +86,59 @@ Examples are based on the standard project structure and provide additional file 1. Configure your zkApp: `zk config` - The command prompts guide you to add a deploy alias to your project `config.json` file. The deploy alias can be anything you want. For this example, use `berkeley`. + The command prompts guide you to add a deploy alias to your project `config.json` file. - For Berkeley Testnet, use: + The deploy alias can be anything you want. For more details, see [Deploy alias](/zkapps/tutorials/deploying-to-a-network#deploy-alias) in Tutorial 3: Deploy to a Live Network. + + For this example on Berkeley Testnet, use: + + - Deploy alias name: `berkeley` + + This example uses `berkeley`, but the deploy alias name can be anything and does not have to match the network name. - - name: `berkeley` - Mina GraphQL API URL: `https://proxy.berkeley.minaexplorer.com/graphql` - - transaction fee: `0.1` + + - Transaction fee to use when deploying: `0.1` + + - Account to pay transaction fees: Create a new fee payer pair + +1. When prompted to choose an account to pay transaction feeds, select to use a different account: + + ```sh + Use a different account (select to see options) + ``` + + If this is the first time you run the `zk config` command, you see these options: + + ```text + ❯ Recover fee payer account from an existing base58 private key + Create a new fee payer key pair + ``` + +The option to choose another account is shown only if the user has a cached fee payer account. + +1. Next, select to create a new fee payer key pair: + + ```sh + Create a new fee payer key pair + NOTE: the private key will be stored in plain text on this computer. + ``` + +1. When prompted, give an alias to your new fee payer key pair. For this example, use `sudoku`: + + ```sh + Create an alias for this account: sudoku + ``` + + Your key pairs and deploy alias are created. 1. Fund your fee payer account. - Follow the prompts to request tMINA. + Follow the prompts to request tMINA. For this example, your MINA address is populated on the Testnet Faucet. tMINA arrives at your address when the next block is produced (~3 minutes). 1. Deploy to Testnet: `zk deploy` - Follow the prompts. For details, see [how to deploy a zkApp](how-to-deploy-a-zkapp). + Follow the prompts and select the `sudoku` deploy alias. For details, see [how to deploy a zkApp](how-to-deploy-a-zkapp). ### Option B: Start your own project @@ -119,7 +157,7 @@ Examples are based on the standard project structure and provide additional file none ``` - For your selected UI framework, follow the prompts. + For your selected UI framework, follow the prompts. See [How to Write a zkApp UI](/zkapps/how-to-write-a-zkapp-ui). To see the files that were created, change to the project (whatever you called ``) directory and run the `ls` command or open the directory in a code editor, such as VS Code. @@ -133,13 +171,51 @@ Examples are based on the standard project structure and provide additional file 1. Configure your zkApp: `zk config` - The command prompts guide you to add a deploy alias to your project `config.json` file. The deploy alias can be anything you want. For this example, use `berkeley`. + The command prompts guide you to add a deploy alias to your project `config.json` file. + + The deploy alias can be anything you want. For more details, see [Deploy alias](/zkapps/tutorials/deploying-to-a-network#deploy-alias) in Tutorial 3: Deploy to a Live Network. + + For this example on Berkeley Testnet, use: + + - Deploy alias name: `berkeley` + + This example uses `berkeley`, but the deploy alias name can be anything and does not have to match the network name. + + - Mina GraphQL API URL: `https://proxy.berkeley.minaexplorer.com/graphql` + + - Transaction fee to use when deploying: `0.1` + + - Account to pay transaction fees: Create a new fee payer pair + +1. When prompted to choose an account to pay transaction fees, select to use a different account: - For Berkeley Testnet, use: + ```sh + Use a different account (select to see options) + ``` - - name: `berkeley` - - Mina GraphQL API URL: `https://proxy.berkeley.minaexplorer.com/graphql` - - transaction fee: `0.1` + If this is the first time you run the `zk config` command, you see these options: + + ```text + ❯ Recover fee payer account from an existing base58 private key + Create a new fee payer key pair + ``` + +The option to choose another account is shown only if the user has a cached fee payer account. + +1. Next, select to create a new fee payer key pair: + + ```sh + Create a new fee payer key pair + NOTE: the private key will be stored in plain text on this computer. + ``` + +1. When prompted, give an alias to your new fee payer key pair. For this example, use `sudoku`: + + ```sh + Create an alias for this account: sudoku + ``` + + Your key pairs and deploy alias are created. 1. Fund your fee payer account. diff --git a/docs/zkapps/how-zkapps-work.mdx b/docs/zkapps/how-zkapps-work.mdx index beb3d9bfe..aaeeb47e6 100644 --- a/docs/zkapps/how-zkapps-work.mdx +++ b/docs/zkapps/how-zkapps-work.mdx @@ -137,7 +137,7 @@ When the prover function runs in a web browser, the smart contract outputs a pro 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 +### zkApp state - On-chain state describes state that lives on the Mina blockchain. @@ -151,13 +151,7 @@ If you anticipate your state to be larger, or if the state accumulates per user ### Off-chain state -:::info - -Off-chain state is not yet supported. - -::: - -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. +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 self-hosted off-chain state stored elsewhere. Mina doesn't offer an out-of-the-box solution for off-chain storage. 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. diff --git a/docs/zkapps/tutorials/03-deploying-to-a-network.mdx b/docs/zkapps/tutorials/03-deploying-to-a-network.mdx index 1fbcc34a1..a2559d8a0 100644 --- a/docs/zkapps/tutorials/03-deploying-to-a-network.mdx +++ b/docs/zkapps/tutorials/03-deploying-to-a-network.mdx @@ -16,6 +16,8 @@ keywords: - mina testnet --- +import ResponsiveVideo from '@site/src/components/common/ResponsiveVideo'; + :::info zkApp programmability is not yet available on the Mina Mainnet. You can get started now by deploying zkApps to the Berkeley Testnet. @@ -28,7 +30,7 @@ In previous tutorials, you learned how to deploy and run transactions on a local In this tutorial, you use the `zk config` command to create a deploy alias, request tMINA funds to pay for transaction fees, and deploy a project to a live network. -Mina zkApps are available only on feature-complete Berkeley, Mina's public Testnet. This tutorial reuses the `Square` contract that you created in [Tutorial 1: Hello World](hello-world). +Mina zkApps are available only on feature-complete Berkeley, Mina's public Testnet. This tutorial reuses the `Square` contract that you created in [Tutorial 1: Hello World](hello-world). ## Prerequisites @@ -289,6 +291,14 @@ When you change the smart contract code, the associated verification key also ch For a typical smart contract, permissions are set to allow only proof authorization: the proof in zero knowledge proof. You learn more about setting permissions in a later tutorial. +## Video + +Watch this tutorial for a step-by-step guide and extra explanations on how to deploy a zkApp. + + + +The video is provided for educational purposes and uses earlier versions of the zkApp CLI and SnarkyJS, so there are some differences. This tutorial is tested with a specific version of the zkApp CLI and SnarkyJS. + ## Conclusion Congratulations! You have successfully deployed a smart contract to a live network. diff --git a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx index b46408259..3ea947a68 100644 --- a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx +++ b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx @@ -2,7 +2,7 @@ title: 'Tutorial 4: Build a zkApp UI in the Browser with React' hide_title: true sidebar_label: 'Tutorial 4: Build a zkApp UI in the Browser with React' -description: Guided steps to implement a browser UI using ReactJS that interacts with a smart contract running on the Berkeley Testnet. +description: Guided steps to implement a browser UI that interacts with a smart contract running on the Berkeley Testnet. keywords: - smart contracts - zkapps @@ -24,450 +24,604 @@ zkApp programmability is not yet available on the Mina Mainnet. You can get star ::: -## Overview +You're making excellent progress in your zkApp journey: -In previous tutorials, we've seen how to [write zkApps](hello-world) and [deploy them to a network](deploying-to-a-network). +- In the [Hello World](hello-world) tutorial, you built a basic zkApp smart contract with SnarkyJS. +- In [Tutorial 3: Deploy to a Live Network](deploying-to-a-network), you used the `zk config` command to create a deploy alias. -In this tutorial, we will implement a browser UI using ReactJS that interacts with a smart contract running on Berkeley. +In this tutorial, you implement a browser UI using ReactJS that interacts with a smart contract. -We will discuss how to setup our project, implement its functionality, and deploy it to Github Pages. +## Prerequisites -If you would like to try out the application before going through the tutorial, you can do so on an instance already deployed to a Github Pages [here](https://es92.github.io/zkApp-examples/index.html). Extra info is printed to the console as well when it is run, to give an idea of what it is doing internally. +- Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. +- The Auro Wallet browser extension wallet that supports interactions with zkApps. See [Install a Wallet](/using-mina/install-a-wallet) and create a MINA account. -### What we will build +This tutorial has been tested with: -The application we build will implement the following: +- [Mina zkApp CLI](https://github.com/o1-labs/zkapp-cli) version 0.11.0 +- [SnarkyJS](https://www.npmjs.com/package/snarkyjs) version 0.12.1 +- [Auro Wallet](https://www.aurowallet.com/) version 2.2.3 -1. Loading a public key from an extension-based wallet (tested with [Auro](https://www.aurowallet.com/) >= 2.1.2) -2. Checking if the public key has funds, and direct the user to the faucet if not. -3. Connecting to example zkApp `Add` smart contract, already deployed on Berkeley testnet at a fixed address. -4. A button that when clicked sends a transaction. -5. A button that when clicked requests the latest state of the smart contract. +## Use the working application first -Like in tutorial 3, we will provide a couple of helper files, so we can focus on the React implementation itself. What is special about these helpers though, is that they use a webworker. This ensures the UI thread isn't blocked during long computations like compiling a smart contract or proving a transaction. +Before you go through the tutorial steps, take a look at a working zkApp UI example that has already been deployed to GitHub Pages. -This example uses an RPC endpoint. An in-browser Mina node is in the works, which will provide full node level security to your users, in the browser. +1. In a Chrome web browser with the Auro wallet extension, go to [https://ymekuria.github.io/04-zkapp-browser-ui/index.html](https://ymekuria.github.io/04-zkapp-browser-ui/index.html). +1. When prompted, select **Connect** to let the website view your Auro wallet account. +1. In network dropdown menu in the wallet UI, select the **Berkeley** network: +
+ Select Berkeley network in the wallet +
-## Project setup +## High-Level Overview -First, setup a new project with +In this tutorial, you build an application that: -```sh -$ zk project 04-zkapp-browser-ui --ui next -``` +1. Loads a public key from an extension-based wallet. +1. Checks if the public key has funds and if not, directs the user to the faucet. +1. Connects to the example zkApp `Add` smart contract that is already deployed on Berkeley Testnet at a fixed address. +1. Implements a button that sends a transaction. +1. Implements a button that requests the latest state of the smart contract. +1. Deploys the zkApp to GitHub Pages. -On the prompts that appear, select: +Like previous tutorials, you use the provided [example files](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/) so you can focus on the React implementation itself. -1. Do you want your NextJS project to use TypeScript? `yes` -2. Do you want to setup your project for GitHub pages? `yes` +This example uses an RPC endpoint. -This will create a new project with two folders instead of just one: +## Create a project -- `contracts`: This stores your smart contract code -- `ui`: This is where you will write your ui +The `zk project` command can scaffold the UI for your project. -We will be using the default contract (`Add`), so all we'll be doing is building it for use from our ui. +1. Create or change to a directory where you have write privileges. -To do this, enter the `contracts` folder, and run the build command: +1. Create a project by using the `zk project` command: -```sh -$ cd contracts/ -$ npm run build -``` + ```sh + $ zk project 04-zkapp-browser-ui + ``` -In making your own zkApp, you will need to edit files in the `contracts` folder, and rebuild before accessing it from your UI. + The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `next`: -## Implementing the UI + ``` + ? Create an accompanying UI project too? … +❯ next + svelte + nuxt + empty + none + ``` -Our React UI will have a few components. First, there is the react page itself. In addition though, there is code that uses SnarkyJS. +1. Select **yes** at the `? Do you want to setup your project for deployment to Github Pages? …` prompt. -Because SnarkyJS code is computationally intensive, running it as usual in a script would block our browser's UI thread, causing our page to become unresponsive at times. To solve this, we will put our SnarkyJS code in a web worker. +1. If you are prompted to install the required Next packages, press **y** to proceed. -This will be implemented via 2 helper files: +1. Select **Yes** at the `? Would you like to use TypeScript with this project?` prompt. -- `zkappWorker.ts`: The web worker code itself -- `zkappWorkerClient.ts`: Code that we run from react to interact with the web worker. +1. Select **No** at the `? Would you like to use ESLint with this project?` prompt. -We encourage you to read these files, to understand how they work and to extend them for your own zkApp, but we will not review them in detail here, in favor of spending time on the react code. +1. Select **No** at the `? Would you like to use Tailwind CSS with this project?` prompt. -Download these files from [here](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/pages/zkappWorker.ts) and [here](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/pages/zkappWorkerClient.ts), and place them in your `ui/pages` folder. +Your UI is created in the project directory: `/04-zkapp-browser-ui/ui` with two directories: -### globals.css +- `contracts`: The smart contract code +- `ui`: Where you write your UI code -We will be using an `` link in our application - add the following to the end of `ui/styles/globals.css` to style the link: +1. Change to the `contracts` directory and run `npm install` to install all of the required dependencies: -```css -a { - color: blue; -} -``` + ```sh + $ cd contracts + $ npm install + ``` + +1. Change to the `ui` directory and run `npm install` to install all of the required dependencies: + + ```sh + $ cd ../ui + $ npm install + ``` + +## Project structure + +For all projects, you run `zk` commands from the root of your `04-zkapp-browser-ui` project directory. + +For this tutorial, run the UI commands from the local `/04-zkapp-browser-ui/ui/` directory. + +Files that contain the UI code are in the `ui/src/pages` directory. + +Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. + +### Preparing the project + +Start by deleting the default `rm index.page.tsx` file that comes with a new project. + +1. Change to the `ui/src/pages` directory: + + ```sh + $ cd ui/src/pages + ``` -### Running the react app +1. Delete the `index.page.tsx` file so that you have a clean project to work with: -To run the react app, open up two new terminals in the `ui` folder. In one, type: + ```sh + $ rm index.page.tsx + ``` + +## Build the default contract + +This tutorial uses the default contract `Add` that is always scaffolded with the `zk project` command. + +Go back to root of your project directory: ```sh -$ npm run dev +$ cd 04-zkapp-browser-ui ``` -And in the other, +To build the default contract to use in the UI: ```sh -$ npm run ts-watch +$ cd contracts +$ npm run build ``` -The first of these starts hosting your application, by default at `localhost:3000`. Your browser will refresh automatically when your page has changes. +If you were to make your own zkApp outside of this tutorial, edit files in the `contracts` folder and then rebuild the contract before accessing it from your UI. -The second shows typescript errors. You can watch this as you develop to check for type errors. +## Implement the UI -### Implementing the react app +The React UI has several components: the React page itself and the code that uses SnarkyJS. -Open up `ui/pages/_app.page.tsx` in your editor. You can find the full contents for this file [here](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/pages/_app.page.tsx) for reference. +Because SnarkyJS code is computationally intensive, it's helpful to use web workers. A web worker handles requests from users to ensure the UI thread isn't blocked during long computations like compiling a smart contract or proving a transaction. -Edit the contents so it looks like this: +1. Download the helper files from the `examples/zkapps/04-zkapp-browser-ui` directory on GitHub to your local `/04-zkapp-browser-ui/ui/src/pages` directory: -```ts - 1 import '../styles/globals.css' - 2 import { useEffect, useState } from "react"; - 3 import './reactCOIServiceWorker'; - 4 - 5 import ZkappWorkerClient from './zkappWorkerClient'; - 6 - 7 import { PublicKey, Field } from 'snarkyjs'; - 8 - 9 let transactionFee = 0.1; - 10 - 11 export default function App() { - 12 return
- 13 } - 14 -``` + - [zkappWorker.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/zkappWorker.ts) + - [zkappWorkerClient.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/zkappWorkerClient.ts) + +1. Review each helper file to see how they work and how you can extend them for your own zkApp. + + - `zkappWorker.ts` is the web worker code + - `zkappWorkerClient.ts` is the code that is run from React to interact with the web worker + +### Run the React app + +To run the React app, run commands from two different terminal windows in your local `/04-zkapp-browser-ui/ui/` directory. + +1. In the first terminal window: + + ```sh + $ npm run dev + ``` + + This command starts hosting your application at the `localhost:3000` default location. + + The zkApp UI in the web browser shows the current state of the zkApp and has buttons to send a transaction and get the latest state. + + Your browser refreshes automatically when your page has changes. Tip: If you are already hosting a different process on 3000, be sure to stop that process. + +1. If prompted, request funds from the Testnet Faucet to fund your fee payer account. + + Follow the prompts to request tMINA. For this tutorial, your MINA address is populated on the Testnet Faucet. tMINA arrives at your address when the next block is produced (~3 minutes). + +1. And in the second terminal window: -This just sets up our react project, with the imports we'll need, and an empty component. + ```sh + $ npm run ts-watch + ``` -Now, we'll add state to our app: + This command shows TypeScript errors. As you develop your application, you can watch this window to check for type errors. + +### Implement the React app + +1. Download the [index.page.tsx](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/index.page.tsx) file to your local `/04-zkapp-browser-ui/ui/src/pages` directory. + + - `index.page.tsx` contains the main logic for the browser UI that is ready to deploy to GitHub Pages + +The `import` statements set up your React project with the required imports. The `export` statement creates a placeholder empty component: ```ts -... - 11 export default function App() { - 12 let [state, setState] = useState({ - 13 zkappWorkerClient: null as null | ZkappWorkerClient, - 14 hasWallet: null as null | boolean, - 15 hasBeenSetup: false, - 16 accountExists: false, - 17 currentNum: null as null | Field, - 18 publicKey: null as null | PublicKey, - 19 zkappPublicKey: null as null | PublicKey, - 20 creatingTransaction: false, - 21 }); - 22 - 23 // ------------------------------------------------------- - 24 - 25 return
-... + 1 import { useEffect, useState } from 'react'; + 2 import './reactCOIServiceWorker'; + 3 import ZkappWorkerClient from './zkappWorkerClient'; + 4 import { PublicKey, Field } from 'snarkyjs'; + 5 import GradientBG from '../components/GradientBG.js'; + 6 import styles from '../styles/Home.module.css'; + 7 + 8 let transactionFee = 0.1; + 9 + 10 export default function Home() { + 11 return
+ 12 } ``` -This creates mutable state that we can reference in our UI, and update as our application runs. You can learn more about react state and useState [here](https://reactjs.org/docs/hooks-state.html). +### Add state -Next, we'll add a function to setup our application: +This export statement creates mutable state that you can reference in the UI. The state updates as the application runs: -```ts +```ts ignore ... - 23 // ------------------------------------------------------- - 24 // Do Setup - 25 - 26 useEffect(() => { - 27 (async () => { - 28 if (!state.hasBeenSetup) { - 29 const zkappWorkerClient = new ZkappWorkerClient(); - 30 - 31 console.log('Loading SnarkyJS...'); - 32 await zkappWorkerClient.loadSnarkyJS(); - 33 console.log('done'); - 34 - 35 await zkappWorkerClient.setActiveInstanceToBerkeley(); - 36 - 37 // TODO - 38 } - 39 })(); - 40 }, []); - 41 - 42 // ------------------------------------------------------- + 10 export default function Home() { + 11 let [state, setState] = useState({ + 12 zkappWorkerClient: null as null | ZkappWorkerClient, + 13 hasWallet: null as null | boolean, + 14 hasBeenSetup: false, + 15 accountExists: false, + 16 currentNum: null as null | Field, + 17 publicKey: null as null | PublicKey, + 18 zkappPublicKey: null as null | PublicKey, + 19 creatingTransaction: false, + 20 }); + 21 + 22 const [displayText, setDisplayText] = useState(''); + 23 const [transactionlink, setTransactionLink] = useState(''); ... ``` -We use the react feature "useEffect", so that this is only run once. See more on useEffect [here](https://reactjs.org/docs/hooks-effect.html). We further gate running this effect by a boolean `hasBeenSetup` so we don't run this more than once. +To learn more about `useState` Hooks, see [Built-in React Hooks](https://react.dev/reference/react#state-hooks) in the React API Reference documentation. + +### Add a function -This is also where we setup our web worker client. This will interact with our web worker running SnarkyJS code, so that that code doesn't block the UI thread. +This code adds a function to set up the application: + +- The Boolean `hasBeenSetup` ensures that the react feature `useEffect` is run only once. To learn more about `useEffect` Hooks, see [useEffect](https://react.dev/reference/react/useEffect) in the React API Reference documentation. + +- This code also sets up your web worker client that interacts with the web worker running SnarkyJS code to ensure the computationally heavy SnarkyJS code doesn't block the UI thread. ```ts ... - 35 await zkappWorkerClient.setActiveInstanceToBerkeley(); + 25 // ------------------------------------------------------- + 26 // Do Setup + 27 + 28 useEffect(() => { + 29 async function timeout(seconds: number): Promise { + 30 return new Promise((resolve) => { + 31 setTimeout(() => { + 32 resolve(); + 33 }, seconds * 1000); + 34 }); + 35 } 36 - 37 const mina = (window as any).mina; - 38 - 39 if (mina == null) { - 40 setState({ ...state, hasWallet: false }); - 41 return; - 42 } + 37 (async () => { + 38 if (!state.hasBeenSetup) { + 39 setDisplayText('Loading web worker...'); + 40 console.log('Loading web worker...'); + 41 const zkappWorkerClient = new ZkappWorkerClient(); + 42 await timeout(5); 43 - 44 const publicKeyBase58: string = (await mina.requestAccounts())[0]; - 45 const publicKey = PublicKey.fromBase58(publicKeyBase58); + 44 setDisplayText('Done loading web worker'); + 45 console.log('Done loading web worker'); 46 - 47 console.log('using key', publicKey.toBase58()); + 47 await zkappWorkerClient.setActiveInstanceToBerkeley(); 48 - 49 console.log('checking if account exists...'); - 50 const res = await zkappWorkerClient.fetchAccount({ - 51 publicKey: publicKey! - 52 }); - 53 const accountExists = res.error == null; - 54 - 55 // TODO - 56 } + 49 // TODO + 50 } + 51 })(); + 52 }, []); + 53 + 54 // ------------------------------------------------------- ... ``` -Continuing, we load our zkApp in the web worker. We load the contract, compile it, create a instance of it at a fixed address, and get its current state: +### Load the zkApp in the web worker -```ts +This code loads the contract and compiles it: + +```ts ignore ... - 53 const accountExists = res.error == null; - 54 - 55 await zkappWorkerClient.loadContract(); - 56 - 57 console.log('compiling zkApp'); - 58 await zkappWorkerClient.compileContract(); - 59 console.log('zkApp compiled'); - 60 - 61 const zkappPublicKey = PublicKey.fromBase58( - 62 'B62qiqD8k9fAq94ejkvzaGEV44P1uij6vd6etGLxcR4dA8ZRZsxkwvR' - 63 ); - 64 - 65 await zkappWorkerClient.initZkappInstance(zkappPublicKey); - 66 - 67 console.log('getting zkApp state...'); - 68 await zkappWorkerClient.fetchAccount({ publicKey: zkappPublicKey }) - 69 const currentNum = await zkappWorkerClient.getNum(); - 70 console.log('current state:', currentNum.toString()); - 71 - 72 // TODO - 73 } + 47 await zkappWorkerClient.setActiveInstanceToBerkeley(); + 48 + 49 const mina = (window as any).mina; + 50 + 51 if (mina == null) { + 52 setState({ ...state, hasWallet: false }); + 53 return; + 54 } + 55 + 56 const publicKeyBase58: string = (await mina.requestAccounts())[0]; + 57 const publicKey = PublicKey.fromBase58(publicKeyBase58); + 58 + 59 console.log('using key', publicKey.toBase58()); + 60 setDisplayText(`Using key:${publicKey.toBase58()}`); + 61 + 62 setDisplayText('Checking if fee payer account exists...'); + 63 console.log('Checking if fee payer account exists...'); + 64 + 65 const res = await zkappWorkerClient.fetchAccount({ + 66 publicKey: publicKey!, + 67 }); + 68 const accountExists = res.error == null; + 69 + 70 // TODO + 71 } ... ``` -And lastly for this function, we update the state of the react app: +### Create an instance -```ts +This code creates an instance of the contract at a fixed address and gets its current state: + +```ts ignore ... - 70 console.log('current state:', currentNum.toString()); + 68 const accountExists = res.error == null; + 69 + 70 await zkappWorkerClient.loadContract(); 71 - 72 setState({ - 73 ...state, - 74 zkappWorkerClient, - 75 hasWallet: true, - 76 hasBeenSetup: true, - 77 publicKey, - 78 zkappPublicKey, - 79 accountExists, - 80 currentNum - 81 }); - 82 } - 83 })(); + 72 console.log('Compiling zkApp...'); + 73 setDisplayText('Compiling zkApp...'); + 74 await zkappWorkerClient.compileContract(); + 75 console.log('zkApp compiled'); + 76 setDisplayText('zkApp compiled...'); + 77 + 78 const zkappPublicKey = PublicKey.fromBase58( + 79 'B62qjshG3cddKthD6KjCzHZP4oJM2kGuC8qRHN3WZmKH5B74V9Uddwu' + 80 ); + 81 + 82 await zkappWorkerClient.initZkappInstance(zkappPublicKey); + 83 + 84 console.log('Getting zkApp state...'); + 85 setDisplayText('Getting zkApp state...'); + 86 await zkappWorkerClient.fetchAccount({ publicKey: zkappPublicKey }); + 87 const currentNum = await zkappWorkerClient.getNum(); + 88 console.log(`Current number in zkApp state: ${currentNum.toString()}`); + 89 setDisplayText(''); + 90 + 91 // TODO + 92 } ... ``` -Now that we have finished setting up our UI, we write a new effect, that waits for the account to exist, if it didn't exist before. +### Update the state of the React app -If the account has been newly created for example, it will need to be funded from the faucet. We'll add in our UI later a link to request funds for new accounts. +And finally for this function, update the state of the React app: -```ts +```ts ignore ... - 86 // ------------------------------------------------------- - 87 // Wait for account to exist, if it didn't - 88 - 89 useEffect(() => { - 90 (async () => { - 91 if (state.hasBeenSetup && !state.accountExists) { - 92 for (;;) { - 93 console.log('checking if account exists...'); - 94 const res = await state.zkappWorkerClient!.fetchAccount({ - 95 publicKey: state.publicKey! - 96 }) - 97 const accountExists = res.error == null; - 98 if (accountExists) { - 99 break; -100 } -101 await new Promise((resolve) => setTimeout(resolve, 5000)); -102 } -103 setState({ ...state, accountExists: true }); -104 } -105 })(); -106 }, [state.hasBeenSetup]); -107 -108 // ------------------------------------------------------- + 89 setDisplayText(''); + 90 + 91 setState({ + 92 ...state, + 93 zkappWorkerClient, + 94 hasWallet: true, + 95 hasBeenSetup: true, + 96 publicKey, + 97 zkappPublicKey, + 98 accountExists, + 99 currentNum +100 }); +101 } +102 })(); +103 }, []); ... ``` -Moving on, we'll create functions that are triggered when a button is pressed by a user. +### Write a new effect -First, a function that will send a transaction: +Now that the UI setup is finished, a new effect waits for the account to exist if it didn't exist before. -```ts +If the account has been newly created, it must be funded from the faucet. + +Later, you add a link in the UI to request funds for new accounts. + +```ts ignore 105-128 ... -108 // ------------------------------------------------------- -109 // Send a transaction -110 -111 const onSendTransaction = async () => { -112 setState({ ...state, creatingTransaction: true }); -113 console.log('sending a transaction...'); -114 -115 await state.zkappWorkerClient!.fetchAccount({ -116 publicKey: state.publicKey! -117 }); -118 -119 await state.zkappWorkerClient!.createUpdateTransaction(); -120 -121 console.log('creating proof...'); -122 await state.zkappWorkerClient!.proveUpdateTransaction(); -123 -124 console.log('getting Transaction JSON...'); -125 const transactionJSON = await state.zkappWorkerClient!.getTransactionJSON() -126 -127 console.log('requesting send transaction...'); -128 const { hash } = await (window as any).mina.sendTransaction({ -129 transaction: transactionJSON, -130 feePayer: { -131 fee: transactionFee, -132 memo: '', -133 }, -134 }); -135 -136 console.log( -137 'See transaction at https://berkeley.minaexplorer.com/transaction/' + hash -138 ); -139 -140 setState({ ...state, creatingTransaction: false }); -141 } -142 -143 // ------------------------------------------------------- +105 // ------------------------------------------------------- +106 // Wait for account to exist, if it didn't +107 +108 useEffect(() => { +109 (async () => { +110 if (state.hasBeenSetup && !state.accountExists) { +111 for (;;) { +112 setDisplayText('Checking if fee payer account exists...'); +113 console.log('Checking if fee payer account exists...'); +114 const res = await state.zkappWorkerClient!.fetchAccount({ +115 publicKey: state.publicKey!, +116 }); +117 const accountExists = res.error == null; +118 if (accountExists) { +119 break; +120 } +121 await new Promise((resolve) => setTimeout(resolve, 5000)); +122 } +123 setState({ ...state, accountExists: true }); +124 } +125 })(); +126 }, [state.hasBeenSetup]); +127 +128 // ------------------------------------------------------- ... ``` -And second, a function that will get the latest zkApp state: +### Create functions for UI buttons -```ts +Functions can be triggered when a button is pressed by a user. + +First, code for a function that sends a transaction: + +```ts 128- ... -143 // ------------------------------------------------------- -144 // Refresh the current state -145 -146 const onRefreshCurrentNum = async () => { -147 console.log('getting zkApp state...'); -148 await state.zkappWorkerClient!.fetchAccount({ -149 publicKey: state.zkappPublicKey! -150 }) -151 const currentNum = await state.zkappWorkerClient!.getNum(); -152 console.log('current state:', currentNum.toString()); -153 -154 setState({ ...state, currentNum }); -155 } -156 -157 // -------------------------------------------------------... +128 // ------------------------------------------------------- +129 // Send a transaction +130 +131 const onSendTransaction = async () => { +132 setState({ ...state, creatingTransaction: true }); +133 +134 setDisplayText('Creating a transaction...'); +135 console.log('Creating a transaction...'); +136 +137 await state.zkappWorkerClient!.fetchAccount({ +138 publicKey: state.publicKey!, +139 }); +140 +141 await state.zkappWorkerClient!.createUpdateTransaction(); +142 +143 setDisplayText('Creating proof...'); +144 console.log('Creating proof...'); +145 await state.zkappWorkerClient!.proveUpdateTransaction(); +146 +147 setDisplayText('Requesting send transaction...'); +148 const { hash } = await (window as any).mina.sendTransaction({ +149 const transactionJSON = await state.zkappWorkerClient!.getTransactionJSON(); +150 +151 setDisplayText('Getting transaction JSON...'); +152 console.log('Getting transaction JSON...'); +153 const { hash } = await (window as any).mina.sendTransaction({ +154 transaction: transactionJSON, +155 feePayer: { +156 fee: transactionFee, +157 memo: '', +158 }, +159 }); +160 +161 const transactionLink = `https://berkeley.minaexplorer.com/transaction/${hash}`; +162 console.log(`View transaction at ${transactionLink}`); +163 +164 setTransactionLink(transactionLink); +165 setDisplayText(transactionLink); +166 +167 setState({ ...state, creatingTransaction: false }); +168 }; +169 +170 // ------------------------------------------------------- ``` -Lastly, we will update the `return
` placeholder we originally inserted, with a ui to show the user the state of our application: +And second, code for a function that gets the latest zkApp state: -```ts +```ts 170-186 ... -157 // ------------------------------------------------------- -158 // Create UI elements -159 -160 let hasWallet; -161 if (state.hasWallet != null && !state.hasWallet) { -162 const auroLink = 'https://www.aurowallet.com/'; -163 const auroLinkElem = ( -164 -165 {' '} -166 [Link]{' '} -167 -168 ); -169 hasWallet = ( -170
-171 {' '} -172 Could not find a wallet. Install Auro wallet here: {auroLinkElem} -173
-174 ); -175 } -176 -177 let setupText = state.hasBeenSetup -178 ? 'SnarkyJS Ready' -179 : 'Setting up SnarkyJS...'; -180 let setup = ( -181
-182 {' '} -183 {setupText} {hasWallet} -184
-185 ); -186 -187 let accountDoesNotExist; -188 if (state.hasBeenSetup && !state.accountExists) { -189 const faucetLink = -190 'https://faucet.minaprotocol.com/?address=' + state.publicKey!.toBase58(); -191 accountDoesNotExist = ( -192
-193 Account does not exist. Please visit the faucet to fund this account -194 -195 {' '} -196 [Link]{' '} -197 -198
-199 ); -200 } -201 -202 let mainContent; -203 if (state.hasBeenSetup && state.accountExists) { -204 mainContent = ( -205
-206 -213
Current Number in zkApp: {state.currentNum!.toString()}
-214 -215
-216 ); -217 } -218 -219 return ( -220
-221 {setup} -222 {accountDoesNotExist} -223 {mainContent} -224
-225 ); -226 } +170 // ------------------------------------------------------- +171 // Refresh the current state +172 +173 const onRefreshCurrentNum = async () => { +174 console.log('Getting zkApp state...'); +175 setDisplayText('Getting zkApp state...'); +176 +177 await state.zkappWorkerClient!.fetchAccount({ +178 publicKey: state.zkappPublicKey!, +179 }); +180 const currentNum = await state.zkappWorkerClient!.getNum(); +181 setState({ ...state, currentNum }); +182 console.log(`Current number in zkApp state: ${currentNum.toString()}`); +183 setDisplayText(''); +184 }; +185 +186 // -------------------------------------------------------... +``` + +### Update placeholder +Replace the `
` placeholder with a UI to show the user the state of your application: + +```ts 186-268 +... +186 // ------------------------------------------------------- +187 // Create UI elements +188 +189 let hasWallet; +190 if (state.hasWallet != null && !state.hasWallet) { +191 const auroLink = 'https://www.aurowallet.com/'; +192 const auroLinkElem = ( +193 +194 [Link]{' '} +195 +196 ); +197 hasWallet = ( +198
+199 Could not find a wallet. Install Auro wallet here: {auroLinkElem} +200
+201 ); +202 } +203 +204 const stepDisplay = transactionlink ? ( ); +205 +206 View transaction +207 +208 ) : ( +209 displayText +210 ); +211 +212 let setup = ( +213
+217 {stepDisplay} +218 {hasWallet} +219
+220 ); +221 +222 let accountDoesNotExist; +223 if (state.hasBeenSetup && !state.accountExists) { +224 const faucetLink = +225 'https://faucet.minaprotocol.com/?address=' + state.publicKey!.toBase58(); +226 accountDoesNotExist = ( +227
+228 Account does not exist. Please visit the faucet to fund this account +229 +230 [Link]{' '} +231 +232
+233 ); +234 } +235 +236 let mainContent; +237 if (state.hasBeenSetup && state.accountExists) { +238 mainContent = ( +239
+240
+241 Current Number in zkApp: {state.currentNum!.toString()}{' '} +242
+243 +250 +253
+254 ); +255 } +256 +257 return ( +258 +259
+260
+261 {setup} +262 {accountDoesNotExist} +263 {mainContent} +264
+265
+266
+267 ); +268 } ``` -We divide our UI into 3 sections: +The UI has three sections: - `setup` lets the user know when the zkApp has finished loading. - `accountDoesNotExist` gives the user a link to the faucet if their account hasn't been funded. -- `mainContent` shows the current state of the zkApp, and buttons to interact with it. +- `mainContent` shows the current state of the zkApp and buttons to interact with it. + + The buttons allow the user to create a transaction and refresh the current state of the application by triggering the `onSendTransaction()` and `onRefreshCurrentNum()` functions shown in the code. + +And that's it! You have reviewed the code for your application. -The buttons allow the user to create a transaction, or refresh the current state of the application, by triggering the `onSendTransaction()` and `onRefreshCurrentNum()` functions we wrote above. +If you've been using `npm run dev`, you can now interact with the application on `localhost:3000`. The application has all of the functionality that is implemented in this tutorial. -And that's it! We've finished the code for our application. +## Deploying the UI to GitHub Pages -If you've been using `npm run dev`, you should now be able to interact with this application on `localhost:3000`, with all the functionality we've implemented over the tutorial. +Before you can deploy your project to GitHub Pages, you must push it to a new GitHub repository. -## Deploying the UI to Github Pages +- The GitHub repo must have the same name as the project name. +- In this tutorial, the project name is `04-zkapp-browser-ui`. +- The `zk project` command created the correct project name strings for `04-zkapp-browser-ui` in the `next.config.js` and `src/pages/reactCOIServiceWorker.ts` files. -To deploy our project to Github, first push it to a new Github repo. The Github repo must have the same name as the project name when we ran zk project above (in this example, `04-zkapp-browser-ui`). If not, change the existing project name strings in `next.config.js`, and `pages/reactCOIServiceWorker.ts` to your repo name. +To deploy the UI, run the `npm run deploy` command in your local `/04-zkapp-browser-ui/ui/` directory. -To deploy, just run `npm run deploy` in the `ui` directory. After the script builds your application, uploads it to Github, and Github processes it, your application will be available at: +After the script builds your application, uploads it to GitHub, and GitHub processes it, your application is available at: ``` https://.github.io//index.html @@ -475,8 +629,8 @@ https://.github.io//index.html ## Conclusion -We have built a React UI for our zkApp, to allow users to interact with our smart contract and send transactions to Berkeley Testnet! +Congratulations! You built a React UI for your zkApp. The UI allows users to interact with your smart contract and send transactions to Berkeley Testnet. -You can build a UI for your application using any UI framework, not just React. The zkApp CLI will also soon provide support for simultaneously creating SvelteKit and NuxtJS projects too - stay tuned! +You can build a UI for your application using any UI framework, not just React. The zkApp CLI also supports SvelteKit and NuxtJS projects. -Checkout [Tutorial 5](common-types-and-functions) to learn about different SnarkyJS types you can use in your application. +You are ready to continue with [Tutorial 5: Common Types and Functions](common-types-and-functions) to learn about different SnarkyJS types you can use in your application. diff --git a/docs/zkapps/tutorials/05-common-types-and-functions.mdx b/docs/zkapps/tutorials/05-common-types-and-functions.mdx index 026323d2f..aebf8e4d9 100644 --- a/docs/zkapps/tutorials/05-common-types-and-functions.mdx +++ b/docs/zkapps/tutorials/05-common-types-and-functions.mdx @@ -2,7 +2,7 @@ title: 'Tutorial 5: Common Types and Functions' hide_title: true sidebar_label: 'Tutorial 5: Common Types and Functions' -description: Higher-order types are built from Fields and are useful for your development. Learn how to create custom types. +description: Higher-order types are built from Fields. Create custom types to build your own strings. Create compound data types with the Struct. keywords: - smart contracts - zkapps @@ -14,33 +14,40 @@ keywords: - zk - blockchain - mina + - custom types + - basic types + - circuits + - struct --- +import ResponsiveVideo from '@site/src/components/common/ResponsiveVideo'; + :::info zkApp programmability is not yet available on the Mina Mainnet. You can get started now by deploying zkApps to the Berkeley Testnet. ::: -:::note -This tutorial was last tested with [SnarkyJS](https://www.npmjs.com/package/snarkyjs) 0.8.0. +# Tutorial 5: Common Types and Functions -::: +In previous tutorials, you learned how to deploy smart contracts to the network interact with them from a React UI and NodeJS. -# Tutorial 5: Common Types and Functions +In this tutorial, you learn about types you can use when building with SnarkyJS. Earlier tutorials mostly use the `Field` type. SnarkyJS provides other higher-order types built from Fields that are useful for zkApp development and expand the possibilities for more applications. + +All types are defined in the [SnarkyJS / Modules / Types](/zkapps/snarkyjs-reference/modules/Types) API reference documentation. -In previous tutorials, we've seen how to deploy smart contracts to the network, and we've interacted with them from both a React UI and NodeJS. +The [example project](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src) includes a [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/main.ts) file that shows all of the concepts presented in this tutorial, along with smart contracts showing more advanced usage of some of the concepts, particularly Merkle Trees. -In this tutorial, we will talk about more types that are useful when building with SnarkyJS, so you can build more applications. So far, we've mostly been using the `Field` type. SnarkyJS provides other higher-order types built from Fields, that will be useful for your development. +## Prerequisites -You can find all of these on the [SnarkyJS Reference page](../snarkyjs-reference), for their full API documentation. +This tutorial has been verified with [Mina zkApp CLI](https://github.com/o1-labs/zkapp-cli) version `0.11.0` and [SnarkyJS](https://www.npmjs.com/package/snarkyjs) `0.12.1`. -There is also a project [here](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src), with a [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/main.ts) demoing the concepts presented in this tutorial, along with smart contracts showing more advanced usage of some of the concepts, particularly Merkle Trees. +Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. ## Basic Types -To start, we'll discuss 5 basic types derived from the Fields: +Five basic types are derived from Fields: - [Bool](../snarkyjs-reference/classes/Bool) - [UInt32](../snarkyjs-reference/classes/UInt32) @@ -48,9 +55,9 @@ To start, we'll discuss 5 basic types derived from the Fields: - [Int64](../snarkyjs-reference/classes/Int64) - [Character](../snarkyjs-reference/classes/Character) -These each have their usual programming language semantics. +Each type has the usual programming language semantics. -For example, we can have the following code: +For example, the following code: ```ts const num1 = UInt32.from(40); @@ -82,7 +89,7 @@ console.log(`char1 === char2: ${char1EqualsChar2.toString()}`); console.log(`Fields in char1: ${char1.toFields().length}`); ``` -And when run it'll print to the console: +This result prints to the console when the code is run: ``` num1 === num2: true @@ -96,20 +103,20 @@ Fields in char1: 1 ## More Advanced Types -4 more advanced types are: +Four advanced types are: - [CircuitString](../snarkyjs-reference/classes/CircuitString) - [PrivateKey](../snarkyjs-reference/classes/PrivateKey) - [PublicKey](../snarkyjs-reference/classes/Types.PublicKey) - [Signature](../snarkyjs-reference/classes/Signature) -All arguments passed into smart contracts need to be arguments SnarkyJS can understand. This means that we can't just pass normal strings - we need to pass in strings that have been wrapped to be compatible with circuits, which is what `Struct` accomplishes. +All arguments passed into smart contracts must be arguments SnarkyJS can consume. You cannot pass normal strings. Instead, you must pass in strings that are wrapped to be compatible with circuits. This is accomplished with `Struct`. -One special thing to note, is that the default `CircuitString` has a max length of 128 characters. This is because, under the hood, SnarkyJS types have to be fixed length. However, the `CircuitString` API abstracts this away and can be used like a dynamic length string, with the only caveat being the max length. +The default `CircuitString` has a maximum length of 128 characters because SnarkyJS types must be fixed length. However, the `CircuitString` API abstracts this restriction away and can be used like a dynamic length string with the maximum length caveat. -We'll see in the following section how to create custom types, where you could for example build your own strings, modified to whatever length you would like. +You can create custom types to build your own strings, modified to whatever length you want. -A brief example of using these: +A brief example of custom types: ```ts const str1 = CircuitString.fromString('abc..xyz'); @@ -154,19 +161,21 @@ signature verified for data2: true Fields in signature: 256 ``` -Small but important note: Make sure that you never use the private key above (or any private key that's publicly accessible) in a real application! +Observe and follow best practices for your key security. Make sure that you never use the private key in this example output, or any private key that's publicly accessible, in a real application. -If you're curious why there are 255 Fields in a private key and 256 in a signature - the reason for this is cryptographic in nature: Elliptic curve scalars are most efficiently represented in a SNARK as an array of bits, and the bit length of these scalars happens to be 255. +There are 255 Fields in a private key and 256 Fields in a signature. If you are curious about the reason for this, the answer is cryptographic in nature: Elliptic curve scalars are most efficiently represented in a SNARK as an array of bits, and the bit length of these scalars is 255. ## Struct -A special type is [Struct](../snarkyjs-reference#struct), which lets you create your own compound data types. +You can create your own compound data types with the special [Struct](../snarkyjs-reference#struct) type. + +Define a Struct as one or more data types that SnarkyJS understands. For example, Field, higher-order types built into SnarkyJS based on Field, or other Struct types defined by you. You can also define methods on your Struct to act upon this data type. -Your Struct can be defined as one or more data types that SnarkyJS understands, i.e. Field, higher-order types built into SnarkyJS based on Field, or other Struct types defined by you. You can also define methods on your Struct to act upon this data type, if desired, but doing so is optional. +The following example demonstrates how to use `Struct` to implement a `Point` structure and an array of points of length 8 structure. -See the following for an example of how to use `Struct`, implementing a `Point` structure, and an array of points of length 8 structure. +In SnarkyJS, programs are compiled into fixed-sized circuits. This means that data structures it consumes must also be a fixed size. -SnarkyJS compiles programs into fixed sized circuits. This means that data structures it consumes must also be a fixed size, and is why we declare the array in `Points8` structure to be a static size of 8 in the example below. +To meet the fixed-size requirement, this code declares the array in `Points8` structure to be a static size of 8. ```ts class Point extends Struct({ x: Field, y: Field }) { @@ -194,23 +203,24 @@ const points8: Points8 = { points }; console.log(`points8 JSON: ${JSON.stringify(points8)}`); ``` -Which prints the following to the console: +The console output: ``` pointSum Fields: 11,6 points8 Fields: {"points":[{"x":"0","y":"0"},{"x":"1","y":"10"},{"x":"2","y":"20"},{"x":"3","y":"30"},{"x":"4","y":"40"},{"x":"5","y":"50"},{"x":"6","y":"60"},{"x":"7","y":"70"}]} ``` -## Control flow +## Control Flow -There are two functions which help do control flow within SnarkyJS: +Two functions help do control flow in SnarkyJS: - [Provable.if](../snarkyjs-reference/classes/Circuit#if) -- [Provable.switch](../snarkyjs-reference/classes/Circuit#switch) + Similar to a ternary in JavaScript -`Provable.if` is similar to a ternary in JavaScript. `Provable.switch` is similar to a switch case statement in JavaScript. +- [Provable.switch](../snarkyjs-reference/classes/Circuit#switch) + Similar to a switch case statement in JavaScript -With these, you can write conditionals inside SnarkyJS. +You can write conditionals inside SnarkyJS with these functions. For example: @@ -261,30 +271,30 @@ inputSumAbs: 5 largest: 22 ``` -Note that when using `Provable.if`, like in a JS ternary, both branches are executed. Unlike normal programming, because SnarkyJS under the hood is creating a zk circuit, there is no primitive for if statements where only one branch is executed. +Both branches are executed when using `Provable.if`, like in a JavaScript ternary. Because SnarkyJS is creating a zk circuit, there is no primitive for `if` statements where only one branch is executed. ## Assertions and Constraints SnarkyJS functions are compiled to generate circuits. -When a transaction is proven in SnarkyJS, SnarkyJS is proving that the program logic is computed according to the written program, and all assertions are holding true. +When a transaction is proven in SnarkyJS, the proof is that the program logic is computed according to the written program, and all assertions are holding true. -We've seen assertions already, with `a.assertEquals(b)`, which we've often used. There is also `.assertTrue()` available on the Bool class. +In previous tutorials, you learned `a.assertEquals(b)`. The `.assertTrue()` is available on the Bool class. -Circuits in SnarkyJS currently have a fixed maximum size. Each operation performed in a function counts towards this maximum size. This maximum size is currently equivalent to the following: +Circuits in SnarkyJS have a fixed maximum size. Each operation performed in a function counts towards this maximum size. This maximum size is equivalent to: - about 5,200 hashes on two fields - about 2,600 hashes on four fields - about `2^17` field multiplies - about `2^17` field additions -If a program is too large to fit into these constraints, it can be broken up into multiple recursive proof verifications. See more on how to do this in the section [here](../snarkyjs/recursion). +If a program is too large to fit into these constraints, it can be broken up into multiple recursive proof verifications. See [Recursion](../snarkyjs/recursion). ## Merkle Trees -Lastly, let's go over an example using [merkle trees](../snarkyjs-reference/classes/MerkleTree). Merkle trees are very powerful, since they let us manage large amounts of data within a circuit. In the [project corresponding to this tutorial](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src), you can find a full reference for the example here. The contract can be found in [BasicMerkleTreeContract.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/BasicMerkleTreeContract.ts), and the example can be found in a section of [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/main.ts). +You can use [Merkle trees](../snarkyjs-reference/classes/MerkleTree) to manage large amounts of data within a circuit. The power of Merkle trees is demonstrated in the [05-common-types-and-functions/src](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src) reference project for this tutorial. See the [BasicMerkleTreeContract.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/BasicMerkleTreeContract.ts) contract and [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/main.ts) that demonstrates how contracts interact with Merkle trees and how to construct them. -Start off by importing `MerkleTree`: +The first step is to import `MerkleTree`: ```ts import { @@ -294,18 +304,20 @@ import { } from 'snarkyjs' ``` -Merkle Trees can be created in your application like so: +To create Merkle trees in your application: ```ts const height = 20; const tree = new MerkleTree(height); ``` -The height variable determines how many leaves are available to your application. A height of 20 for example will lead to a tree with `2^(20-1)`, or 524,288 leaves. +The height variable determines how many leaves are available to the application. For example, a height of 20 leads to a tree with `2^(20-1)`, or 524,288 leaves. + +Merkle trees in smart contracts are stored as the hash of the Merkle tree's root. Smart contract methods that update the Merkle root can take a _witness_ of the change as an argument. The [MerkleMapWitness](/zkapps/snarkyjs-reference/classes/MerkleMapWitness) represents the Merkle path to the data for which inclusion is being proved. -Merkle trees in smart contracts are stored as the hash of the merkle tree's root. Smart contract methods which update the merkle root can take a "witness" of the change as an argument, which represents the merkle path to the data for which inclusion is being proved. +A contract stores the root of a Merkle tree, where each leaf stores a number, and the smart contract has an `update` function that adds a number to the leaf. -Here is a simple example of a contract that stores the root of a merkle tree, where each leaf stores a number, and the smart contract has an `update` function that adds a number to the leaf. As an example of putting a condition on a leaf update, the `update` function checks that the number added was less than 10. +For example, to put a condition on a leaf update, the `update` function checks that the number added was less than 10: ```ts ... @@ -339,7 +351,7 @@ Here is a simple example of a contract that stores the root of a merkle tree, wh } ``` -And code to interact with it: +The code to interact with the smart contract: ```ts // initialize the zkapp @@ -399,13 +411,15 @@ console.log( ); ``` -While in this example leaves are fields, you can put more variables in a leaf by instead hashing an array of fields, and setting a leaf to that. +In this example, leaves are fields. However, you can put more variables in a leaf by hashing an array of fields and setting a leaf to that hash. -You can find this complete example in the [project directory](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src), as well as a more advanced example `LedgerContract`, which implements a basic ledger of tokens, including checks that the sender has signed their transaction and that the amount the sender has sent matches the amount the receiver receives. +This complete example is in the [project directory](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src). + +A more advanced example `LedgerContract` implements a basic ledger of tokens, including checks that the sender has signed their transaction and that the amount the sender has sent matches the amount the receiver receives. ## Merkle Map -Lastly, let's go over an example using [merkle maps](../snarkyjs-reference/classes/MerkleMap). These allow us to implement key value stores. +See the API reference documentation for the [MerkleMap](../snarkyjs-reference/classes/MerkleMap) class you can use to implement key-value stores. The API for Merkle Maps is similar to Merkle Trees, just instead of using an index to set a leaf, one uses a key: @@ -460,7 +474,7 @@ It can be used inside smart contracts with a witness, similar to merkle trees } ``` -With (abbreviated) code to interact with it, similar to the merkle tree example above: +With (abbreviated) code to interact with it, similar to the Merkle tree example above: ```ts const map = new MerkleMap(); @@ -485,13 +499,17 @@ const txn1 = await Mina.transaction(deployerAccount, () => { ... ``` -MerkleMaps can be used to implement many useful patterns. For example: +You use [MerkleMaps](/zkapps/snarkyjs-reference/classes/MerkleMap) to implement many useful patterns. For example: - A key value store from public keys to booleans, of token accounts to whether they've participated in a voted yet. - A nullifier that privately tracks if an input was used, without revealing it. ## Conclusion -Congrats! We have finished reviewing more common types and functions in SnarkyJS. With this, you should now be capable of writing many advanced smart contracts and zkApps. +Congratulations! You have finished reviewing more common types and functions in SnarkyJS. With this, you should now be capable of writing many advanced smart contracts and zkApps. + +To use more data from your zkApp, check out [Tutorial 6](offchain-storage) to learn how to use off-chain storage. + +## Other Resources -Checkout [Tutorial 6](offchain-storage) to learn how to use off-chain storage, to use more data from your zkApp. + diff --git a/examples/zkapps/04-zkapp-browser-ui/ui/next.config.js b/examples/zkapps/04-zkapp-browser-ui/ui/next.config.js index 29294fced..3cacdfce7 100644 --- a/examples/zkapps/04-zkapp-browser-ui/ui/next.config.js +++ b/examples/zkapps/04-zkapp-browser-ui/ui/next.config.js @@ -1,7 +1,17 @@ /** @type {import('next').NextConfig} */ + +const isProd = process.env.NODE_ENV === 'production' const nextConfig = { reactStrictMode: false, pageExtensions: ['page.tsx', 'page.ts', 'page.jsx', 'page.js'], + + /* Used to serve the Next.js app from a subdirectory (the GitHub repo name) and + * assetPrefix is used to serve assets (JS, CSS, images, etc.) from that subdirectory + * when deployed to GitHub Pages. The assetPrefix needs to be added manually to any assets + * if they're not loaded by Next.js' automatic handling (for example, in CSS files or in a element). + */ + basePath: isProd ? '/04-zkapp-browser-ui': '', + assetPrefix: isProd ? '/04-zkapp-browser-ui': '', webpack(config) { config.resolve.alias = { diff --git a/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/index.page.tsx b/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/index.page.tsx index 2fbe06b3e..162a82297 100644 --- a/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/index.page.tsx +++ b/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/index.page.tsx @@ -85,7 +85,7 @@ export default function Home() { setDisplayText('Getting zkApp state...'); await zkappWorkerClient.fetchAccount({ publicKey: zkappPublicKey }); const currentNum = await zkappWorkerClient.getNum(); - console.log(`Current number in zkApp state: ${currentNum.toString()}`); + console.log(`Current state in zkApp: ${currentNum.toString()}`); setDisplayText(''); setState({ @@ -179,7 +179,7 @@ export default function Home() { }); const currentNum = await state.zkappWorkerClient!.getNum(); setState({ ...state, currentNum }); - console.log(`Current number in zkApp state: ${currentNum.toString()}`); + console.log(`Current state in zkApp: ${currentNum.toString()}`); setDisplayText(''); }; @@ -191,12 +191,12 @@ export default function Home() { const auroLink = 'https://www.aurowallet.com/'; const auroLinkElem = ( - [Link]{' '} + Install Auro wallet here ); hasWallet = (
- Could not find a wallet. Install Auro wallet here: {auroLinkElem} + Could not find a wallet. {auroLinkElem}
); } @@ -225,9 +225,9 @@ export default function Home() { 'https://faucet.minaprotocol.com/?address=' + state.publicKey!.toBase58(); accountDoesNotExist = (
- Account does not exist. Please visit the faucet to fund this account + Account does not exist. - [Link]{' '} + Visit the faucet to fund this fee payer account
); @@ -238,7 +238,7 @@ export default function Home() { mainContent = (
- Current Number in zkApp: {state.currentNum!.toString()}{' '} + Current state in zkApp: {state.currentNum!.toString()}{' '}
- ©2022 Mina. Started by O(1) Labs. + ©2023 Mina. Started by O(1) Labs.
diff --git a/static/img/4_select_berkeley_auro.png b/static/img/4_select_berkeley_auro.png new file mode 100644 index 000000000..2f1f7e4c0 Binary files /dev/null and b/static/img/4_select_berkeley_auro.png differ