From 223cacf7c0c1016efcbb63633828612cc40e836f Mon Sep 17 00:00:00 2001 From: Philip Halsall Date: Wed, 8 Mar 2023 10:58:04 +0800 Subject: [PATCH 01/50] Update to the version number --- docs/node-operators/connecting-to-the-network.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/node-operators/connecting-to-the-network.mdx b/docs/node-operators/connecting-to-the-network.mdx index d081f4eb4..4b600e50c 100644 --- a/docs/node-operators/connecting-to-the-network.mdx +++ b/docs/node-operators/connecting-to-the-network.mdx @@ -30,7 +30,7 @@ sudo apt-get update sudo apt-get install --yes curl unzip mina-mainnet=1.3.1.2-25388a0 ``` -Check that daemon installed correctly by running `mina version`. The output should read `Commit 9b0369c27bb85c8ab2f8725c6e977eb27b53b826 on branch master`. +Check that daemon installed correctly by running `mina version`. The output should read `Commit 25388a0fed9695e8e9d04f75f50c2bae1c9c80db on branch master`. ## Start up a node From 31c267cfdd9af557eb7d7a428116539842414679 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Thu, 13 Jul 2023 10:06:03 -0400 Subject: [PATCH 02/50] WIP curves terms --- docs/glossary.mdx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/glossary.mdx b/docs/glossary.mdx index d591a6e85..d4b431c97 100644 --- a/docs/glossary.mdx +++ b/docs/glossary.mdx @@ -112,6 +112,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. @@ -228,13 +236,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 @@ -292,6 +304,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. From 79cc5d6c72a115aecfb1db0ebef7b25d38155fe3 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Thu, 13 Jul 2023 16:18:07 -0400 Subject: [PATCH 03/50] old doc, stale info, broken links --- docs/node-developers/graphql-api.mdx | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/node-developers/graphql-api.mdx b/docs/node-developers/graphql-api.mdx index 7282141d0..64f975df9 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,11 +143,11 @@ 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 From e27d196be4ed1b6bb28c4431e712658565eb14e3 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Thu, 13 Jul 2023 16:37:23 -0400 Subject: [PATCH 04/50] =?UTF-8?q?add=20Coda=20so=20the=20links=20show=20in?= =?UTF-8?q?=20the=20PR=20and=20add=20the=20GraphQL=20API=20Endpoint=20?= =?UTF-8?q?=E2=80=93=20Mina=20Explorer=20video=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/node-developers/graphql-api.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/node-developers/graphql-api.mdx b/docs/node-developers/graphql-api.mdx index 64f975df9..32298ba8f 100644 --- a/docs/node-developers/graphql-api.mdx +++ b/docs/node-developers/graphql-api.mdx @@ -151,6 +151,7 @@ While exposing the GraphQL API to the internet is not recommended, an implementa ### Resources -- [5-minute introduction video on Mina GraphQL API](http://bit.ly/GraphQLAPIin5) -- [First steps with the Mina GraphQL API](https://garethtdavies.com/crypto/first-steps-with-coda-graphql-api.html) +- [GraphQL API Endpoint – Mina Explorer](https://www.youtube.com/watch?v=RKvg2t561J0) +- [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) Coda - [Introduction to GraphQL](https://graphql.org/learn/) From 7e0aa17e65515e9381d86bdc98b294c81fff7b8f Mon Sep 17 00:00:00 2001 From: Martin Minkov Date: Thu, 13 Jul 2023 15:00:17 -0700 Subject: [PATCH 05/50] docs(archive-node.mdx): add detailed instructions for setting up archive node using Docker and Docker Compose This commit adds comprehensive instructions for setting up and running the archive node using Docker and Docker Compose. This provides users with alternative methods for running the archive node, which can be more convenient and easier to manage. --- docs/node-operators/archive-node.mdx | 139 +++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/docs/node-operators/archive-node.mdx b/docs/node-operators/archive-node.mdx index 793761aa7..dfc73444c 100644 --- a/docs/node-operators/archive-node.mdx +++ b/docs/node-operators/archive-node.mdx @@ -106,6 +106,145 @@ 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. + +If you wish to run the archive node using Docker Compose, you can use the following instructions. + +To get started with installing and running the archive node using Docker Compose, follow the steps below. + +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. From 6c55afeda436454d07a11959e0e52bd3559dd564 Mon Sep 17 00:00:00 2001 From: Barrie Byron Date: Fri, 14 Jul 2023 14:12:46 -0400 Subject: [PATCH 06/50] Update docs/node-operators/archive-node.mdx --- docs/node-operators/archive-node.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/node-operators/archive-node.mdx b/docs/node-operators/archive-node.mdx index dfc73444c..d7e3c74b0 100644 --- a/docs/node-operators/archive-node.mdx +++ b/docs/node-operators/archive-node.mdx @@ -172,7 +172,7 @@ To get started with installing and running the archive node using Docker, follow ## Set up the archive node using Docker Compose -Docker compose is a tool for defining and running multi-container Docker applications. +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. If you wish to run the archive node using Docker Compose, you can use the following instructions. From 83c7018290a5deb0f442f46dafb5476e90fcaa21 Mon Sep 17 00:00:00 2001 From: Barrie Byron Date: Fri, 14 Jul 2023 14:12:57 -0400 Subject: [PATCH 07/50] Update docs/node-operators/archive-node.mdx --- docs/node-operators/archive-node.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/node-operators/archive-node.mdx b/docs/node-operators/archive-node.mdx index d7e3c74b0..930d36be6 100644 --- a/docs/node-operators/archive-node.mdx +++ b/docs/node-operators/archive-node.mdx @@ -175,9 +175,7 @@ To get started with installing and running the archive node using Docker, follow 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. -If you wish to run the archive node using Docker Compose, you can use the following instructions. - -To get started with installing and running the archive node using Docker Compose, follow the steps below. +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/). From 82f335d109f0d53dccc3110abbc5bb58fd26dca7 Mon Sep 17 00:00:00 2001 From: drea-rodriguez <136343145+drea-rodriguez@users.noreply.github.com> Date: Fri, 14 Jul 2023 16:14:26 -0400 Subject: [PATCH 08/50] Update 03-deploying-to-a-network.mdx Adding a video tutorial on how to deploy your first zkApp --- docs/zkapps/tutorials/03-deploying-to-a-network.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/zkapps/tutorials/03-deploying-to-a-network.mdx b/docs/zkapps/tutorials/03-deploying-to-a-network.mdx index 1fbcc34a1..a518df630 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,9 @@ 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). You can watch this tutorial for a step-by-step guide and extra explanations on how to deploy a zkApp. + + ## Prerequisites From 1b38b0bd4a53b43885ce7a5b683cada563049092 Mon Sep 17 00:00:00 2001 From: drea-rodriguez <136343145+drea-rodriguez@users.noreply.github.com> Date: Fri, 14 Jul 2023 16:27:21 -0400 Subject: [PATCH 09/50] Update 05-common-types-and-functions.mdx Adding a video tutorial and how to work with Local Blockchain --- docs/zkapps/tutorials/05-common-types-and-functions.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/zkapps/tutorials/05-common-types-and-functions.mdx b/docs/zkapps/tutorials/05-common-types-and-functions.mdx index 026323d2f..ed5aa47b0 100644 --- a/docs/zkapps/tutorials/05-common-types-and-functions.mdx +++ b/docs/zkapps/tutorials/05-common-types-and-functions.mdx @@ -16,6 +16,8 @@ keywords: - mina --- +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. @@ -495,3 +497,7 @@ MerkleMaps can be used to implement many useful patterns. For example: 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. Checkout [Tutorial 6](offchain-storage) to learn how to use off-chain storage, to use more data from your zkApp. + +## Other Resources + + From ddde09a15873c6325faf95ca8680be1abc5ea057 Mon Sep 17 00:00:00 2001 From: SanabriaRusso Date: Sun, 16 Jul 2023 12:46:35 +0200 Subject: [PATCH 10/50] Update generating-a-keypair.mdx Path to my-wallet directory wrongly assumed to be under ~/. It was changed to $(pwd), as when mounting the directory to the container. --- docs/node-operators/generating-a-keypair.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 752ee5c7b7004172369bf0e12f480b1f25ed9c32 Mon Sep 17 00:00:00 2001 From: Barrie Byron Date: Mon, 17 Jul 2023 11:12:17 -0400 Subject: [PATCH 11/50] Update docs/node-developers/graphql-api.mdx remove --- docs/node-developers/graphql-api.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/node-developers/graphql-api.mdx b/docs/node-developers/graphql-api.mdx index 32298ba8f..b79b3cd5d 100644 --- a/docs/node-developers/graphql-api.mdx +++ b/docs/node-developers/graphql-api.mdx @@ -151,7 +151,6 @@ While exposing the GraphQL API to the internet is not recommended, an implementa ### Resources -- [GraphQL API Endpoint – Mina Explorer](https://www.youtube.com/watch?v=RKvg2t561J0) - [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) Coda - [Introduction to GraphQL](https://graphql.org/learn/) From ecc127e17971d13b49348e2308ee1b03960e5fb5 Mon Sep 17 00:00:00 2001 From: Barrie Byron Date: Mon, 17 Jul 2023 11:12:57 -0400 Subject: [PATCH 12/50] Update docs/node-developers/graphql-api.mdx --- docs/node-developers/graphql-api.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/node-developers/graphql-api.mdx b/docs/node-developers/graphql-api.mdx index b79b3cd5d..5c74aa637 100644 --- a/docs/node-developers/graphql-api.mdx +++ b/docs/node-developers/graphql-api.mdx @@ -152,5 +152,5 @@ While exposing the GraphQL API to the internet is not recommended, an implementa ### Resources - [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) 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/) From 2076cfc34964a42716e72ac13984f8c3150aaf6f Mon Sep 17 00:00:00 2001 From: Barrie Byron Date: Tue, 18 Jul 2023 11:42:05 -0400 Subject: [PATCH 13/50] video before conclusion, version notice --- docs/zkapps/tutorials/03-deploying-to-a-network.mdx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/zkapps/tutorials/03-deploying-to-a-network.mdx b/docs/zkapps/tutorials/03-deploying-to-a-network.mdx index a518df630..a2559d8a0 100644 --- a/docs/zkapps/tutorials/03-deploying-to-a-network.mdx +++ b/docs/zkapps/tutorials/03-deploying-to-a-network.mdx @@ -30,9 +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). You can watch this tutorial for a step-by-step guide and extra explanations on how to deploy a zkApp. - - +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 @@ -293,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. From 1942a63159131fdfa0729c1aae0c2e3fbb6f0b67 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Tue, 18 Jul 2023 16:20:53 -0400 Subject: [PATCH 14/50] up to line 90 for Yoni pairing --- .../tutorials/04-zkapp-ui-with-react.mdx | 489 +++++++++++------- 1 file changed, 316 insertions(+), 173 deletions(-) diff --git a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx index b46408259..537089fc6 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,238 +24,367 @@ 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. +This tutorial has been tested with: -### What we will build +- [Mina zkApp CLI](https://github.com/o1-labs/zkapp-cli) version 0.10.0 +- [SnarkyJS](https://www.npmjs.com/package/snarkyjs) version 0.11.1 +- [Auro Wallet](https://www.aurowallet.com/) version 2.2.1 -The application we build will implement the following: +1. Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. +1. Install the Auro Wallet for Chrome that supports interactions with zkApps. See [Install a Wallet](using-mina/install-a-wallet) and create a MINA account. -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://es92.github.io/zkApp-examples/index.html](https://es92.github.io/zkApp-examples/index.html). +1. When prompted, select **Connect** to let the website view your Auro wallet account. +1. In top middle of the wallet UI, select the **Berkeley** network: +
+ Select Berkeley network in the wallet +
+1. To look at the console to see what happens when the UI loads SnarkyJS and interacts with the smart contract, right-click the browser window and select **Inspect**: +
+ Inspect console in a web browser +
-## 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. +2. Checks if the public key has funds and if not, directs the user to the faucet. +3. Connects to the example zkApp `Add` smart contract that is already deployed on Berkeley Testnet at a fixed address. +4. Implements a button that sends a transaction. +5. Implements a button that requests the latest state of the smart contract. -On the prompts that appear, select: +Like previous tutorials, you use the provided example files 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 -``` - -In making your own zkApp, you will need to edit files in the `contracts` folder, and rebuild before accessing it from your UI. + ```sh + $ zk project 04-zkapp-browser-ui --ui next + ``` +(add the interactive framework select next) +1. At the `? Do you want to setup your project for deployment to Github Pages? …` prompt, select **yes**. -## Implementing the UI +1. If you are prompted to install the required Next packages, press **y** to proceed. -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. At the `? Would you like to use TypeScript with this project? › No / Yes` prompt, select **Yes**. -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. At the `? Would you like to use ESLint with this project? › No / Yes` prompt, select **No**. -This will be implemented via 2 helper files: +1. At the `? Would you like to use Tailwind CSS with this project? › No / Yes` prompt, select **No**. -- `zkappWorker.ts`: The web worker code itself -- `zkappWorkerClient.ts`: Code that we run from react to interact with the web worker. +Your UI is created in the project directory: `/04-zkapp-browser-ui/ui` with two directories: -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. +- `contracts`: The smart contract code +- `ui`: Where you write your UI code -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. +The expected output is: -### globals.css +```text +➜ source zk project 04-zkapp-browser-ui --ui next +✔ Do you want to set up your project for deployment to GitHub Pages? · yes +✔ Would you like to use TypeScript with this project? … No / Yes +✔ Would you like to use ESLint with this project? … No / Yes +✔ Would you like to use Tailwind CSS with this project? … No / Yes +Creating a new Next.js app in /04-zkapp-browser-ui/ui. -We will be using an `` link in our application - add the following to the end of `ui/styles/globals.css` to style the link: +Using npm. -```css -a { - color: blue; -} +Initializing project with template: default ``` -### Running the react app +For this tutorial, you run commands from the root of your `04-zkapp-browser-ui` project directory. You work on files that contain the UI code 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 + ``` + +1. Delete the old files so that you have a clean project to work with: + + ```sh + $ rm index.page.tsx + ``` + +## Build the default contract -To run the react app, open up two new terminals in the `ui` folder. In one, type: +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, you edit files in the `contracts` folder and then rebuild the contract before accessing it from your UI. + +## Implement the UI + +The React UI has a few components: the React page itself and the code that uses SnarkyJS. + +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. + +1. Download the helper files to your local `/04-zkapp-browser-ui/ui/src/pages` directory: + + - [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 understand 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 + +1. In a Chrome web browser with the Auro wallet extension, go to [https://es92.github.io/zkApp-examples/index.html](https://es92.github.io/zkApp-examples/index.html). +1. When prompted, select **Connect** to let the website view your Auro wallet account. +1. In top middle of the wallet UI, select the **Berkeley** network: +
+ Select Berkeley network in the wallet +
+ + +### 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: -The second shows typescript errors. You can watch this as you develop to check for type errors. + ```sh + $ npm run dev + ``` -### Implementing the react app + This command starts hosting your application at the `localhost:3000` default location. Your browser refreshes automatically when your page has changes. -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. +1. In a supported web browser with the Auro wallet extension, go to [https://es92.github.io/zkApp-examples/index.html](https://es92.github.io/zkApp-examples/index.html). -Edit the contents so it looks like this: +1. When prompted, select **Connect** to let the website view your Auro wallet account. + +1. In top middle of the wallet UI, select the **Berkeley** network: +
+ Select Berkeley network in the wallet +
+ +1. If prompted, fund your wallet (get steps from earlier tuto). + +1. And in the second terminal window: + + ```sh + $ npm run ts-watch + ``` + + 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 just set up your React project with the imports you need. The `export` statement creates a placeholder empty component: ```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 + 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 just sets up our react project, with the imports we'll need, and an empty component. +### Add state -Now, we'll add state to our app: +This export statement creates mutable state that you can reference in the UI. The state updates as the application runs: -```ts +```ts ignore ... - 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
+ 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(''); ... ``` -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). +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 -Next, we'll add a function to setup our application: +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 ... - 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(); + 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 // TODO - 38 } - 39 })(); - 40 }, []); - 41 - 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 setDisplayText('Done loading web worker'); + 45 console.log('Done loading web worker'); + 46 + 47 await zkappWorkerClient.setActiveInstanceToBerkeley(); + 48 + 49 // TODO + 50 } + 51 })(); + 52 }, []); + 53 + 54 // ------------------------------------------------------- ... ``` -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. +### Load the zkApp in the web worker -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 loads the contract and compiles it: ```ts ... - 35 await zkappWorkerClient.setActiveInstanceToBerkeley(); - 36 - 37 const mina = (window as any).mina; - 38 - 39 if (mina == null) { - 40 setState({ ...state, hasWallet: false }); - 41 return; - 42 } - 43 - 44 const publicKeyBase58: string = (await mina.requestAccounts())[0]; - 45 const publicKey = PublicKey.fromBase58(publicKeyBase58); - 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 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 } ... ``` -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: +### Create an instance + +This code creates an instance of the contract at a fixed address and gets its current state: ```ts ... - 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()); + 68 const accountExists = res.error == null; + 69 + 70 await zkappWorkerClient.loadContract(); 71 - 72 // TODO - 73 } + 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 } ... ``` -And lastly for this function, we update the state of the react app: +### Update the state of the React app + +And finally for this function, update the state of the React app: ```ts ... @@ -276,9 +405,13 @@ And lastly for this function, we update the state of the react app: ... ``` -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. +### Write a new effect + +Now that the UI setup is finished, a new effect waits for the account to exist if it didn't exist before. -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. +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 ... @@ -308,9 +441,11 @@ If the account has been newly created for example, it will need to be funded fro ... ``` -Moving on, we'll create functions that are triggered when a button is pressed by a user. +### Create functions for UI buttons + +Functions can be triggered when a button is pressed by a user. -First, a function that will send a transaction: +First, code for a function that sends a transaction: ```ts ... @@ -353,7 +488,7 @@ First, a function that will send a transaction: ... ``` -And second, a function that will get the latest zkApp state: +And second, code for a function that gets the latest zkApp state: ```ts ... @@ -374,7 +509,9 @@ And second, a function that will get the latest zkApp state: 157 // -------------------------------------------------------... ``` -Lastly, we will update the `return
` placeholder we originally inserted, with a ui to show the user the state of our application: +### Update placeholder + +Replace the `
` placeholder with a UI to show the user the state of your application: ```ts ... @@ -451,23 +588,29 @@ Lastly, we will update the `return
` placeholder we originally inserted, w ``` -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, or 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 `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 +618,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. From 41375d040958a9417946e5bb12007d8659eda341 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Tue, 18 Jul 2023 17:17:20 -0400 Subject: [PATCH 15/50] code snippets with line numbers --- .../tutorials/04-zkapp-ui-with-react.mdx | 356 ++++++++++-------- 1 file changed, 189 insertions(+), 167 deletions(-) diff --git a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx index 537089fc6..34e893a63 100644 --- a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx +++ b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx @@ -318,7 +318,7 @@ This code adds a function to set up the application: This code loads the contract and compiles it: -```ts +```ts ignore ... 47 await zkappWorkerClient.setActiveInstanceToBerkeley(); 48 @@ -352,7 +352,7 @@ This code loads the contract and compiles it: This code creates an instance of the contract at a fixed address and gets its current state: -```ts +```ts ignore ... 68 const accountExists = res.error == null; 69 @@ -386,22 +386,23 @@ This code creates an instance of the contract at a fixed address and gets its cu And finally for this function, update the state of the React app: -```ts +```ts ignore ... - 70 console.log('current state:', currentNum.toString()); - 71 - 72 setState({ - 73 ...state, - 74 zkappWorkerClient, - 75 hasWallet: true, - 76 hasBeenSetup: true, - 77 publicKey, - 78 zkappPublicKey, - 79 accountExists, - 80 currentNum - 81 }); - 82 } - 83 })(); + 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 }, []); ... ``` @@ -413,31 +414,32 @@ 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 +```ts ignore 105-128 ... - 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]); +105 // ------------------------------------------------------- +106 // Wait for account to exist, if it didn't 107 -108 // ------------------------------------------------------- +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 // ------------------------------------------------------- ... ``` @@ -447,145 +449,165 @@ Functions can be triggered when a button is pressed by a user. First, code for a function that sends a transaction: -```ts -... -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 // ------------------------------------------------------- +```ts 128- ... +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 // ------------------------------------------------------- ``` And second, code for a function that gets the latest zkApp state: -```ts +```ts 170-186 ... -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 // -------------------------------------------------------... +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 +```ts 186-268 ... -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 } - +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 } ``` The UI has three sections: @@ -606,7 +628,7 @@ Before you can deploy your project to GitHub Pages, you must push it to a new Gi - 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 `pages/reactCOIServiceWorker.ts` files. +- 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 the UI, run the `npm run deploy` command in your local `/04-zkapp-browser-ui/ui/` directory. From 9cbd70af979fc921f6f62fed1a2a8b82206c55a7 Mon Sep 17 00:00:00 2001 From: Barrie Byron Date: Wed, 19 Jul 2023 10:10:29 -0400 Subject: [PATCH 16/50] add link to Docker Hub for testing zkApps --- docs/zkapps/how-to-test-a-zkapp.mdx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/zkapps/how-to-test-a-zkapp.mdx b/docs/zkapps/how-to-test-a-zkapp.mdx index efc102052..8e91eae49 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,24 @@ 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: From 828d5a71924aa0a9a92590b7f68a028437a020b8 Mon Sep 17 00:00:00 2001 From: Barrie Byron Date: Wed, 19 Jul 2023 10:14:32 -0400 Subject: [PATCH 17/50] remove extraneous space so link works --- docs/zkapps/how-to-test-a-zkapp.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/zkapps/how-to-test-a-zkapp.mdx b/docs/zkapps/how-to-test-a-zkapp.mdx index 8e91eae49..fbd5aa454 100644 --- a/docs/zkapps/how-to-test-a-zkapp.mdx +++ b/docs/zkapps/how-to-test-a-zkapp.mdx @@ -30,8 +30,7 @@ A Docker image for Mina local networks provides a simple and efficient way to de - 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. +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 From 5dc327e9fd591a0e8ce796796e80185ccda0ac0b Mon Sep 17 00:00:00 2001 From: Martin Minkov Date: Tue, 18 Jul 2023 10:32:13 -0700 Subject: [PATCH 18/50] feat(algolia-config.json): update config for better search results --- algolia-config.json | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) 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"], From 2ff99b2fc6b49b2429d6ff0505645e3497c6ebed Mon Sep 17 00:00:00 2001 From: barriebyron Date: Wed, 19 Jul 2023 17:14:45 -0400 Subject: [PATCH 19/50] edits for first level Mina topics --- docs/about-mina/consensus.mdx | 17 +++++----- docs/about-mina/faq.mdx | 14 ++++---- docs/about-mina/index.mdx | 34 +++++++++---------- docs/about-mina/protocol-architecture.mdx | 6 ++-- .../what-are-zero-knowledge-proofs.mdx | 8 ++--- 5 files changed, 39 insertions(+), 40 deletions(-) diff --git a/docs/about-mina/consensus.mdx b/docs/about-mina/consensus.mdx index 02c8453d0..a49d80ca9 100644 --- a/docs/about-mina/consensus.mdx +++ b/docs/about-mina/consensus.mdx @@ -6,19 +6,20 @@ 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..9f36a9603 100644 --- a/docs/about-mina/faq.mdx +++ b/docs/about-mina/faq.mdx @@ -13,13 +13,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 +27,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..bc4c4f86e 100644 --- a/docs/about-mina/index.mdx +++ b/docs/about-mina/index.mdx @@ -1,41 +1,39 @@ --- -title: Overview +title: Mina Overview --- -# 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. -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..1fe87033d 100644 --- a/docs/about-mina/protocol-architecture.mdx +++ b/docs/about-mina/protocol-architecture.mdx @@ -1,5 +1,5 @@ --- -title: Protocol Architecture +title: Mina Protocol Architecture hide_title: true --- @@ -11,11 +11,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/what-are-zero-knowledge-proofs.mdx b/docs/about-mina/what-are-zero-knowledge-proofs.mdx index deed80b8c..3d4c61aba 100644 --- a/docs/about-mina/what-are-zero-knowledge-proofs.mdx +++ b/docs/about-mina/what-are-zero-knowledge-proofs.mdx @@ -1,13 +1,13 @@ --- -title: What are Zero-Knowledge Proofs? +title: What are 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. From 9974b0bce50796c53634902d77ace9c2aa32beb6 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Wed, 19 Jul 2023 17:27:34 -0400 Subject: [PATCH 20/50] add metadata --- docs/about-mina/consensus.mdx | 6 ++++++ docs/about-mina/faq.mdx | 9 +++++++++ docs/about-mina/index.mdx | 8 +++++++- docs/about-mina/protocol-architecture.mdx | 3 +++ docs/about-mina/what-are-zero-knowledge-proofs.mdx | 5 ++++- 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/docs/about-mina/consensus.mdx b/docs/about-mina/consensus.mdx index a49d80ca9..412720c38 100644 --- a/docs/about-mina/consensus.mdx +++ b/docs/about-mina/consensus.mdx @@ -1,5 +1,11 @@ --- 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'; diff --git a/docs/about-mina/faq.mdx b/docs/about-mina/faq.mdx index 9f36a9603..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"; diff --git a/docs/about-mina/index.mdx b/docs/about-mina/index.mdx index bc4c4f86e..513017713 100644 --- a/docs/about-mina/index.mdx +++ b/docs/about-mina/index.mdx @@ -1,5 +1,11 @@ --- 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 --- # Mina Overview @@ -10,7 +16,7 @@ Mina is an L1 blockchain based on zero-knowledge proofs (ZKP) with smart contrac ## 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 to verify the current consensus state of these networks. diff --git a/docs/about-mina/protocol-architecture.mdx b/docs/about-mina/protocol-architecture.mdx index 1fe87033d..217109893 100644 --- a/docs/about-mina/protocol-architecture.mdx +++ b/docs/about-mina/protocol-architecture.mdx @@ -1,6 +1,9 @@ --- 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'; diff --git a/docs/about-mina/what-are-zero-knowledge-proofs.mdx b/docs/about-mina/what-are-zero-knowledge-proofs.mdx index 3d4c61aba..0d72ce8f9 100644 --- a/docs/about-mina/what-are-zero-knowledge-proofs.mdx +++ b/docs/about-mina/what-are-zero-knowledge-proofs.mdx @@ -1,5 +1,8 @@ --- 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'; @@ -8,6 +11,6 @@ import ResponsiveVideo from '@site/src/components/common/ResponsiveVideo'; 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?". Learn 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. From ef147d2dcef634d2faa7b867bc30a65b7b2607b6 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Wed, 19 Jul 2023 17:43:01 -0400 Subject: [PATCH 21/50] deleted topics not in the docs --- docs/about-mina/smart-contracts.mdx | 42 -------------- docs/mina-faq.mdx | 85 ----------------------------- 2 files changed, 127 deletions(-) delete mode 100644 docs/about-mina/smart-contracts.mdx delete mode 100644 docs/mina-faq.mdx 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/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. - From 16e44b56c35defd3fe3da9be917f22c832056c0d Mon Sep 17 00:00:00 2001 From: barriebyron Date: Wed, 19 Jul 2023 17:46:40 -0400 Subject: [PATCH 22/50] image syntax in docs style guide wiki --- docs/image-example.mdx | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 docs/image-example.mdx 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: - - From ac164791c7c60f177bcb133d725f9d374f79fcf0 Mon Sep 17 00:00:00 2001 From: Philip Halsall Date: Thu, 20 Jul 2023 12:10:27 +0800 Subject: [PATCH 23/50] fixing typo --- docs/node-operators/foundation-delegation-program.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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. ::: From a92431a151502441b845236d2157f2232cb6f09f Mon Sep 17 00:00:00 2001 From: barriebyron Date: Thu, 20 Jul 2023 15:43:13 -0400 Subject: [PATCH 24/50] needs GitHub deploy new repo steps, but otherwise good --- .../tutorials/04-zkapp-ui-with-react.mdx | 143 ++++++++---------- static/img/4_select_berkeley_auro.png | Bin 0 -> 58605 bytes 2 files changed, 66 insertions(+), 77 deletions(-) create mode 100644 static/img/4_select_berkeley_auro.png diff --git a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx index 34e893a63..d4001a6fa 100644 --- a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx +++ b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx @@ -33,14 +33,14 @@ In this tutorial, you implement a browser UI using ReactJS that interacts with a ## Prerequisites -This tutorial has been tested with: +- 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. -- [Mina zkApp CLI](https://github.com/o1-labs/zkapp-cli) version 0.10.0 -- [SnarkyJS](https://www.npmjs.com/package/snarkyjs) version 0.11.1 -- [Auro Wallet](https://www.aurowallet.com/) version 2.2.1 +This tutorial has been tested with: -1. Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. -1. Install the Auro Wallet for Chrome that supports interactions with zkApps. See [Install a Wallet](using-mina/install-a-wallet) and create a MINA account. +- [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 ## Use the working application first @@ -48,20 +48,11 @@ Before you go through the tutorial steps, take a look at a working zkApp UI exam 1. In a Chrome web browser with the Auro wallet extension, go to [https://es92.github.io/zkApp-examples/index.html](https://es92.github.io/zkApp-examples/index.html). 1. When prompted, select **Connect** to let the website view your Auro wallet account. -1. In top middle of the wallet UI, select the **Berkeley** network: +1. In network dropdown menu in the wallet UI, select the **Berkeley** network:
Select Berkeley network in the wallet -
-1. To look at the console to see what happens when the UI loads SnarkyJS and interacts with the smart contract, right-click the browser window and select **Inspect**: -
- Inspect console in a web browser
@@ -70,10 +61,11 @@ Before you go through the tutorial steps, take a look at a working zkApp UI exam In this tutorial, you build an application that: 1. Loads a public key from an extension-based wallet. -2. Checks if the public key has funds and if not, directs the user to the faucet. -3. Connects to the example zkApp `Add` smart contract that is already deployed on Berkeley Testnet at a fixed address. -4. Implements a button that sends a transaction. -5. Implements a button that requests the latest state of the smart contract. +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. Like previous tutorials, you use the provided example files so you can focus on the React implementation itself. @@ -88,40 +80,56 @@ The `zk project` command can scaffold the UI for your project. 1. Create a project by using the `zk project` command: ```sh - $ zk project 04-zkapp-browser-ui --ui next + $ zk project 04-zkapp-browser-ui + ``` + + The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `next`: + ``` -(add the interactive framework select next) -1. At the `? Do you want to setup your project for deployment to Github Pages? …` prompt, select **yes**. + ? Create an accompanying UI project too? … +❯ next + svelte + nuxt + empty + none + ``` + +1. Select **yes** at the `? Do you want to setup your project for deployment to Github Pages? …` prompt. 1. If you are prompted to install the required Next packages, press **y** to proceed. -1. At the `? Would you like to use TypeScript with this project? › No / Yes` prompt, select **Yes**. +1. Select **Yes** at the `? Would you like to use TypeScript with this project?` prompt. -1. At the `? Would you like to use ESLint with this project? › No / Yes` prompt, select **No**. +1. Select **No** at the `? Would you like to use ESLint with this project?` prompt. -1. At the `? Would you like to use Tailwind CSS with this project? › No / Yes` prompt, select **No**. +1. Select **No** at the `? Would you like to use Tailwind CSS with this project?` prompt. Your UI is created in the project directory: `/04-zkapp-browser-ui/ui` with two directories: - `contracts`: The smart contract code - `ui`: Where you write your UI code -The expected output is: +1. Change to the `contracts` directory and run `npm install` to install all of the required dependencies: -```text -➜ source zk project 04-zkapp-browser-ui --ui next -✔ Do you want to set up your project for deployment to GitHub Pages? · yes -✔ Would you like to use TypeScript with this project? … No / Yes -✔ Would you like to use ESLint with this project? … No / Yes -✔ Would you like to use Tailwind CSS with this project? … No / Yes -Creating a new Next.js app in /04-zkapp-browser-ui/ui. + ```sh + $ cd contracts + $ npm install + ``` -Using npm. +1. Change to the `ui` directory and run `npm install` to install all of the required dependencies: -Initializing project with template: default -``` + ```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, you run commands from the root of your `04-zkapp-browser-ui` project directory. You work on files that contain the UI code in the `ui/src/pages` 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. @@ -135,7 +143,7 @@ Start by deleting the default `rm index.page.tsx` file that comes with a new pro $ cd ui/src/pages ``` -1. Delete the old files so that you have a clean project to work with: +1. Delete the `index.page.tsx` file so that you have a clean project to work with: ```sh $ rm index.page.tsx @@ -158,35 +166,23 @@ $ cd contracts $ npm run build ``` -If you were to make your own zkApp outside of this tutorial, you edit files in the `contracts` folder and then rebuild the contract before accessing it from your UI. +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. ## Implement the UI -The React UI has a few components: the React page itself and the code that uses SnarkyJS. +The React UI has several components: the React page itself and the code that uses SnarkyJS. 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. -1. Download the helper files to your local `/04-zkapp-browser-ui/ui/src/pages` directory: - - - [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. 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: -1. Review each helper file to understand how they work and how you can extend them for your own zkApp. + - [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) - - `zkappWorker.ts` is the web worker code - - `zkappWorkerClient.ts` is the code that is run from React to interact with the web worker - -1. In a Chrome web browser with the Auro wallet extension, go to [https://es92.github.io/zkApp-examples/index.html](https://es92.github.io/zkApp-examples/index.html). -1. When prompted, select **Connect** to let the website view your Auro wallet account. -1. In top middle of the wallet UI, select the **Berkeley** network: -
- Select Berkeley network in the wallet -
+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 @@ -198,22 +194,15 @@ To run the React app, run commands from two different terminal windows in your l $ npm run dev ``` - This command starts hosting your application at the `localhost:3000` default location. Your browser refreshes automatically when your page has changes. - -1. In a supported web browser with the Auro wallet extension, go to [https://es92.github.io/zkApp-examples/index.html](https://es92.github.io/zkApp-examples/index.html). + 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. -1. When prompted, select **Connect** to let the website view your Auro wallet account. + 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. In top middle of the wallet UI, select the **Berkeley** network: -
- Select Berkeley network in the wallet -
+1. If prompted, request funds from the Testnet Faucet to fund your fee payer account. -1. If prompted, fund your wallet (get steps from earlier tuto). + 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: @@ -227,9 +216,9 @@ To run the React app, run commands from two different terminal windows in your l 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 + - `index.page.tsx` contains the main logic for the browser UI that is ready to deploy to GitHub Pages -The `import` statements just set up your React project with the imports you need. The `export` statement creates a placeholder empty component: +The `import` statements set up your React project with the required imports. The `export` statement creates a placeholder empty component: ```ts 1 import { useEffect, useState } from 'react'; @@ -616,7 +605,7 @@ The UI has three sections: - `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. - The buttons allow the user to create a transaction, or refresh the current state of the application, by triggering the `onSendTransaction()` and `onRefreshCurrentNum()` functions shown in the code. + 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. @@ -632,7 +621,7 @@ Before you can deploy your project to GitHub Pages, you must push it to a new Gi To deploy the UI, run the `npm run deploy` command in your local `/04-zkapp-browser-ui/ui/` directory. -After the script builds your application, uploads it to GitHub, and Github processes it, your application is 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 diff --git a/static/img/4_select_berkeley_auro.png b/static/img/4_select_berkeley_auro.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1f7e4c012f860adf69e9245b35f1f73a8771b5 GIT binary patch literal 58605 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 Date: Fri, 21 Jul 2023 00:08:14 +0400 Subject: [PATCH 25/50] update footer and social links --- src/constants.ts | 6 +++--- src/theme/Footer/index.tsx | 39 ++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 6e086b708..ffcd3d2a0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,10 +1,10 @@ export const SocialLinks = { GitHub: 'https://github.com/MinaProtocol/mina', Twitter: 'https://twitter.com/minaprotocol', - WeChat: 'https://forums.minaprotocol.com/', + WeChat: 'https://minafoundation.notion.site/Follow-Mina-s-WeChat-and-Weibo-Official-Accounts-91226f4ea59b402ebf0cb3b40f764d69', YouTube: 'https://www.youtube.com/c/minaprotocol', - Discord: 'https://discord.gg/minaprotocol', - Telegram: 'http://bit.ly/MinaTelegram', + Discord: 'https://bit.ly/MinaDiscord', + Telegram: 'https://forums.minaprotocol.com/', Support: 'https://support.minaprotocol.com', }; diff --git a/src/theme/Footer/index.tsx b/src/theme/Footer/index.tsx index be616988b..c628d90ab 100644 --- a/src/theme/Footer/index.tsx +++ b/src/theme/Footer/index.tsx @@ -108,6 +108,11 @@ function Footer(): JSX.Element | null {

  • Documentation
  • +
  • + + zkIgnite, Cohort 2 + +
  • Write a zkApp
  • @@ -116,11 +121,7 @@ function Footer(): JSX.Element | null { Run a Node -
  • - - Join Genesis - -
  • +
  • @@ -163,24 +164,29 @@ function Footer(): JSX.Element | null {
  • - Community + Ecosystem
    • - Welcome + Community
    • - - Genesis Program + + Grants
    • - - Testnet Leaderboard + + Work with Mina
    • - - Careers + + Community Blog + +
    • +
    • + + Mina Foundation
    @@ -192,14 +198,11 @@ function Footer(): JSX.Element | null { Discord
  • - Forums + Mina Research
  • Github
  • -
  • - Contact Us -
  • @@ -226,7 +229,7 @@ function Footer(): JSX.Element | null {
    - ©2022 Mina. Started by O(1) Labs. + ©2023 Mina. Started by O(1) Labs.
    From 88fa22d31de1bab07185ec286e99769e7a2d9f2a Mon Sep 17 00:00:00 2001 From: barriebyron Date: Fri, 21 Jul 2023 08:11:18 -0400 Subject: [PATCH 26/50] update fee payer workflow --- docs/zkapps/how-to-deploy-a-zkapp.mdx | 15 ++-------- docs/zkapps/how-to-write-a-zkapp.mdx | 42 +++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 18 deletions(-) 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-write-a-zkapp.mdx b/docs/zkapps/how-to-write-a-zkapp.mdx index fe4c73865..a827bdf93 100644 --- a/docs/zkapps/how-to-write-a-zkapp.mdx +++ b/docs/zkapps/how-to-write-a-zkapp.mdx @@ -86,21 +86,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. - 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) + ``` + +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 From 419fea62d1ebc8c518f0a91c2b4f65a640664054 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Fri, 21 Jul 2023 09:14:57 -0400 Subject: [PATCH 27/50] add DAO, on-chain, off-chain, and update a few more terms --- docs/glossary.mdx | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/glossary.mdx b/docs/glossary.mdx index d591a6e85..cb3a465ca 100644 --- a/docs/glossary.mdx +++ b/docs/glossary.mdx @@ -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 that 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. @@ -130,6 +134,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. @@ -158,7 +166,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 +222,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. Transactions are executed instantly, speeding up the transaction process and reducing 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. @@ -252,9 +268,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 From e6fd63f6e161001613060c61e6170a96b145ec30 Mon Sep 17 00:00:00 2001 From: Angu$ Date: Sat, 22 Jul 2023 16:08:47 +0100 Subject: [PATCH 28/50] fix zkappWorker links and path --- docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx index b46408259..82a37308e 100644 --- a/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx +++ b/docs/zkapps/tutorials/04-zkapp-ui-with-react.mdx @@ -90,7 +90,7 @@ This will be implemented via 2 helper files: 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. -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. +Download these files from [here](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/zkappWorker.ts) and [here](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/src/pages/zkappWorkerClient.ts), and place them in your `ui/src/pages` folder. ### globals.css From f0316dd5295830b1f9259a9590c265d49af0f144 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Mon, 24 Jul 2023 16:02:29 -0400 Subject: [PATCH 29/50] add terms that keep coming up in engineering convos and partnership products --- docs/glossary.mdx | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/glossary.mdx b/docs/glossary.mdx index d4b431c97..f59f711e8 100644 --- a/docs/glossary.mdx +++ b/docs/glossary.mdx @@ -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. @@ -138,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. @@ -166,7 +174,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 @@ -222,6 +230,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. Transactions are executed instantly, speeding up the transaction process and reducing 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. @@ -264,9 +280,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 From 38bb47a7b6a261e92cb058c05f6124dc10fb7a39 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Mon, 24 Jul 2023 16:03:41 -0400 Subject: [PATCH 30/50] get the glossary back from main, updated in wrong branch, oops --- docs/glossary.mdx | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/docs/glossary.mdx b/docs/glossary.mdx index cb3a465ca..d591a6e85 100644 --- a/docs/glossary.mdx +++ b/docs/glossary.mdx @@ -82,7 +82,7 @@ Generating a SNARK for a computation output can be thought of as compressing tha ### consensus -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. +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. ### consensus node @@ -98,10 +98,6 @@ 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 that 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. @@ -134,10 +130,6 @@ 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. @@ -166,7 +158,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, 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. +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). ## L @@ -222,14 +214,6 @@ 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. Transactions are executed instantly, speeding up the transaction process and reducing 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. @@ -268,17 +252,9 @@ 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 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. +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. ### prover function From 274e45c7f4255041c9e6bb0eb0298df5b7750491 Mon Sep 17 00:00:00 2001 From: barriebyron Date: Tue, 25 Jul 2023 11:52:20 -0400 Subject: [PATCH 31/50] WIP tuto 5 --- .../tutorials/05-common-types-and-functions.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/zkapps/tutorials/05-common-types-and-functions.mdx b/docs/zkapps/tutorials/05-common-types-and-functions.mdx index ed5aa47b0..70b796d9a 100644 --- a/docs/zkapps/tutorials/05-common-types-and-functions.mdx +++ b/docs/zkapps/tutorials/05-common-types-and-functions.mdx @@ -32,17 +32,17 @@ This tutorial was last tested with [SnarkyJS](https://www.npmjs.com/package/snar # Tutorial 5: Common Types and Functions -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. +In previous tutorials, you learned how to deploy smart contracts to the network interact with them from a React UI and NodeJS. -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. +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. -You can find all of these on the [SnarkyJS Reference page](../snarkyjs-reference), for their full API documentation. +All types are defined in the [SnarkyJS / Modules / Types](/zkapps/snarkyjs-reference/modules/Types) API reference documentation. -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. +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) 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. ## Basic Types -To start, we'll discuss 5 basic types derived from the Fields: +Five basic types are derived from the Fields: - [Bool](../snarkyjs-reference/classes/Bool) - [UInt32](../snarkyjs-reference/classes/UInt32) @@ -50,9 +50,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); From 208fa0c5dcf54e93ce5ca48652b26a9fa5845b49 Mon Sep 17 00:00:00 2001 From: ymekuria Date: Tue, 25 Jul 2023 17:02:41 -0600 Subject: [PATCH 32/50] feat(index.page.tsx): update ui to display current zkapp state --- .../zkapps/04-zkapp-browser-ui/ui/src/pages/index.page.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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..baacfbb33 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(''); }; @@ -238,7 +238,7 @@ export default function Home() { mainContent = (
    - Current Number in zkApp: {state.currentNum!.toString()}{' '} + Current state in zkApp: {state.currentNum!.toString()}{' '}