Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tutorial 3 to CI #567

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
39 changes: 39 additions & 0 deletions .github/workflows/test-tutorials.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,42 @@ jobs:
git config --global user.email "[email protected]"
git config --global user.name "Test"
npx ts-node scripts/tutorial-runner.ts docs/zkapps/tutorials/01-hello-world.mdx

deploying-network:
timeout-minutes: 25
runs-on: ubuntu-latest
services:
mina-local-network:
image: o1labs/mina-local-network:rampup-latest-lightnet
env:
NETWORK_TYPE: 'single-node'
PROOF_LEVEL: 'none'
ports:
- 3085:3085
- 5432:5432
- 8080:8080
- 8181:8181
# TODO: Disable logging for container as the workaround of long post-job-cleanup phase
# - Will be fixed by improving logging as part of the work on:
# - https://hub.docker.com/r/o1labs/mina-local-network
options: --log-driver=none
steps:
- name: Wait for Mina Network readiness
uses: o1-labs/wait-for-mina-network-action@v1
with:
mina-graphql-port: 8080
max-attempts: 60
polling-interval-ms: 10000
- uses: actions/checkout@v2
- uses: actions/setup-node@v3
with:
node-version: 20
- name: Run tutorial
env:
USE_LOCAL_NETWORK: 'true'
continue-on-error: false
run: |
npm ci
git config --global user.email "[email protected]"
git config --global user.name "Test"
npx ts-node scripts/tutorial-runner.ts docs/zkapps/tutorials/03-deploying-to-a-network.mdx
208 changes: 106 additions & 102 deletions docs/zkapps/tutorials/01-hello-world.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ This Hello World tutorial helps you get started with o1js, zkApps, and programmi

In this step-by-step tutorial, you learn to code a zkApp from start to finish.

You will:
You will:

- Write a basic smart contract that stores a number as on-chain state.
- The contract logic allows this number to be replaced only by its square; for example, 3 -> 9 -> 81, and so on.
- The contract logic allows this number to be replaced only by its square; for example, 3 -> 9 -> 81, and so on.
- Create a project using the [Mina zkApp CLI](https://www.npmjs.com/package/zkapp-cli)
- Write your smart contract code
- Use a local Mina blockchain to interact with your smart contract.

Later tutorials introduce more concepts and patterns.
Later tutorials introduce more concepts and patterns.

The full source code for this tutorial is provided in the [examples/zkapps/01-hello-world](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/01-hello-world) directory on GitHub. While you're there, give the `/docs2` repository a star so that other zk developers can learn to build a zkApp!
The full source code for this tutorial is provided in the [examples/zkapps/01-hello-world](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/01-hello-world) directory on GitHub. While you're there, give the `/docs2` repository a star so that other zk developers can learn to build a zkApp!

:::info

Expand All @@ -65,66 +65,67 @@ Now that you have the tooling installed, you can start building your application
1. Create or change to a directory where you have write privileges.
1. Now, create a project using the `zk project` command:

```sh
$ zk project 01-hello-world
```

The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`:

```
? Create an accompanying UI project too? …
next
svelte
nuxt
empty
❯ none
```
The expected output is:

```sh
✔ Create an accompanying UI project too? · none
✔ UI: Set up project
✔ Initialize Git repo
✔ Set up project
✔ NPM install
✔ NPM build contract
✔ Set project name
✔ Git init commit

Success!

Next steps:
cd 01-hello-world
git remote add origin <your-repo-url>
git push -u origin main
```

The `zk project` command creates the `01-hello-world` directory that contains the scaffolding for your project, including tools such as the Prettier code formatting tool, the ESLint static code analysis tool, and the Jest JavaScript testing framework.
```sh
$ zk project 01-hello-world
```

The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`:

```
? Create an accompanying UI project too? …
next
svelte
nuxt
empty
❯ none
```

The expected output is:

```sh
✔ Create an accompanying UI project too? · none
Copy link
Contributor

Choose a reason for hiding this comment

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

out of curiosity - does the tutorial runner parse this to figure out what option to select? or how does it work?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, it only parses shell commands if they begin with $, rest is ignored

Copy link
Contributor

Choose a reason for hiding this comment

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

so how does it select the none option then? there's a second snippet which shows the choice but it also doesn't have a leading $

Copy link
Member Author

Choose a reason for hiding this comment

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

Or this particular snippet doesn't execute or do anything, it's just rendered to indicate to the reader what to choose

Copy link
Contributor

Choose a reason for hiding this comment

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

I still don't get how the tutorial runner ends up making a choice for the UI project option 😅

Copy link
Member Author

Choose a reason for hiding this comment

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

Ohh!! We have a flag --ui none that the runner is using :D

Copy link
Contributor

Choose a reason for hiding this comment

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

@mitschabaude and @Trivo25

The docs style guide describes the tutorial runner, can we verify the technical accuracy, please?

https://github.com/o1-labs/docs2/wiki/Tutorial-Runner

✔ UI: Set up project
✔ Initialize Git repo
✔ Set up project
✔ NPM install
✔ NPM build contract
✔ Set project name
✔ Git init commit

Success!

Next steps:
cd 01-hello-world
git remote add origin <your-repo-url>
git push -u origin main
```

The `zk project` command creates the `01-hello-world` directory that contains the scaffolding for your project, including tools such as the Prettier code formatting tool, the ESLint static code analysis tool, and the Jest JavaScript testing framework.

1. Change into the `01-hello-world` directory and list the contents:

```sh
$ cd 01-hello-world
$ ls
```

The output shows these results:

```sh
LICENSE
README.md
babel.config.cjs
build
config.json
jest-resolver.cjs
jest.config.js
keys
node_modules
package-lock.json
package.json
src
tsconfig.json
```
```sh
$ cd 01-hello-world
$ ls
```

The output shows these results:

```sh
LICENSE
README.md
Trivo25 marked this conversation as resolved.
Show resolved Hide resolved
babel.config.cjs
build
config.json
jest-resolver.cjs
jest.config.js
keys
node_modules
package-lock.json
package.json
src
tsconfig.json
```

For this tutorial, you run commands from the root of the `01-hello-world` directory as you work in the `src` directory on files that contain the TypeScript code for the smart contract. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory.

Expand All @@ -134,55 +135,55 @@ Start by deleting the default files that come with the new project.

1. To delete the old files:

```sh
$ rm src/Add.ts
$ rm src/Add.test.ts
$ rm src/interact.ts
```
```sh
$ rm src/Add.ts
$ rm src/Add.test.ts
$ rm src/interact.ts
```

1. Now, create the new files for your project:

```sh
$ zk file src/Square
$ touch src/main.ts
```
```sh
$ zk file src/Square
$ touch src/main.ts
```

- The `zk file` command created the `src/Square.ts` and `src/Square.test.ts` test files.
- However, this tutorial does not include writing tests, so you just use the `main.ts` file as a script to interact with the smart contract and observe how it works.
- The `zk file` command created the `src/Square.ts` and `src/Square.test.ts` test files.
- However, this tutorial does not include writing tests, so you just use the `main.ts` file as a script to interact with the smart contract and observe how it works.

In later tutorials, you learn how to interact with a smart contract from the browser, like a typical end user.
In later tutorials, you learn how to interact with a smart contract from the browser, like a typical end user.

3. Now, open `src/index.ts` in a text editor and change it to look like:

```ts src/index.ts
1 import { Square } from './Square.js';
2
3 export { Square };
```
```ts src/index.ts
1 import { Square } from './Square.js';
2
3 export { Square };
```

The `src/index.ts` file contains all of the exports you want to make available for consumption from outside your smart contract project, such as from a UI.
The `src/index.ts` file contains all of the exports you want to make available for consumption from outside your smart contract project, such as from a UI.

## Write the zkApp Smart Contract

Now, the fun part! Write your smart contract in the `src/Square.ts` file.
Now, the fun part! Write your smart contract in the `src/Square.ts` file.

Line numbers are provided for convenience. A final version of the smart contract is provided in the [Square.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Square.ts) example file.

This part of the tutorial walks you through the `Square` smart contract code already completed in the `src/Square.ts` example file.
This part of the tutorial walks you through the `Square` smart contract code already completed in the `src/Square.ts` example file.

### Copy the example
### Copy the example

This tutorial describes each part of the completed code in the [Square.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Square.ts) example file.
This tutorial describes each part of the completed code in the [Square.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Square.ts) example file.

1. First, open the [Square.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Square.ts) example file.

1. Copy the entire contents of the file into your smart contract in the `src/Square.ts` file.

Now you are ready to review the imports in the smart contract.
Now you are ready to review the imports in the smart contract.

### Imports

The `import` statement brings in other packages and dependencies to use in your smart contract.
The `import` statement brings in other packages and dependencies to use in your smart contract.

:::info

Expand Down Expand Up @@ -210,7 +211,7 @@ These items are:

### Smart contract class

Now, review the smart contract in the `src/Square.ts` file.
Now, review the smart contract in the `src/Square.ts` file.

The smart contract called `Square` has one element of on-chain state named `num` of type `Field` as defined by following code:

Expand Down Expand Up @@ -262,20 +263,20 @@ Finally, this code adds the `update()` function:

The function name `update` is arbitrary, but it makes sense for this example. Notice how the `@method` decorator is used because it is intended to be invoked by end users by using a zkApp UI, or as in this case, the `main.ts` script.

This method contains the logic by which end users are allowed to update the zkApp's account state on chain.
This method contains the logic by which end users are allowed to update the zkApp's account state on chain.

A zkApp account is an account is on the Mina blockchain where a zkApp smart contract is deployed. A zkApp account has a verification key associated with it.
A zkApp account is an account is on the Mina blockchain where a zkApp smart contract is deployed. A zkApp account has a verification key associated with it.

In this example, the code specifies:

- If the user provides a number (for example, 9) to the `update()` method that is the square of the existing on-chain state referred to as `num` (for example, 3), then update the `num` value that is stored on-chain to the provided value (in this case, 9).
- If the user provides a number (for example, 9) to the `update()` method that is the square of the existing on-chain state referred to as `num` (for example, 3), then update the `num` value that is stored on-chain to the provided value (in this case, 9).
- If the user provides a number that does not meet these conditions, they are unable to generate a proof or update the on-chain state.

These update conditions are accomplished by using assertions within the method. When a user invokes a method on a smart contract, all assertions must be true to generate the zero-knowledge proof from that smart contract. The Mina network accepts the transaction and updates the on-chain state only if the attached proof is valid. This assertion is how you can achieve predictable behavior in an off-chain execution model.

Notice that `get()` and `set()` methods are used for retrieving and setting on-chain state.
Notice that `get()` and `set()` methods are used for retrieving and setting on-chain state.

- A smart contract retrieves the on-chain account state when it is first invoked if at least one `get()` exists within it.
- A smart contract retrieves the on-chain account state when it is first invoked if at least one `get()` exists within it.

- Similarly, using `set()` changes the transaction to indicate that changes to this particular on-chain state are updated only when the transaction is received by the Mina network if it contains a valid authorization (usually, a valid authorization is a proof).

Expand All @@ -285,13 +286,13 @@ You remember that functions in your smart contract must operate on o1js compatib

Importantly, data passed as an input to a smart contract method in o1js is private and never seen by the network.

You can also store data publicly on-chain when needed, like `num` in this example. A later tutorial covers an example that leverages privacy.
You can also store data publicly on-chain when needed, like `num` in this example. A later tutorial covers an example that leverages privacy.

Congratulations, you have reviewed the complete smart contract code.
Congratulations, you have reviewed the complete smart contract code.

## Interact with a smart contract

Next, write a script that interacts with your smart contract. As before, the complete [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file is provided. Follow these steps to build the `main.ts` file so you can can interact with the smart contract.
Next, write a script that interacts with your smart contract. As before, the complete [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file is provided. Follow these steps to build the `main.ts` file so you can can interact with the smart contract.

### Imports

Expand Down Expand Up @@ -347,8 +348,10 @@ To initialize your local blockchain, add the following code from the [main.ts](h
This local blockchain also provides pre-funded accounts. These lines create local test accounts with test MINA to use for this tutorial:

```ts ignore
const { privateKey: deployerKey, publicKey: deployerAccount } = Local.testAccounts[0];
const { privateKey: senderKey, publicKey: senderAccount } = Local.testAccounts[1];
const { privateKey: deployerKey, publicKey: deployerAccount } =
Local.testAccounts[0];
const { privateKey: senderKey, publicKey: senderAccount } =
Local.testAccounts[1];
```

Tip: To preserve line numbers in your local `main.ts` file, add blank lines as needed after you copy the code snippets.
Expand All @@ -375,13 +378,13 @@ You have the option to combine these commands into one line:
npm run build && node build/src/main.js
```

- The `npm run build` command creates JavaScript code in the `build` directory.
- The `&&` operator links two commands together. The second command runs only if the first command is successful.
- The `npm run build` command creates JavaScript code in the `build` directory.
- The `&&` operator links two commands together. The second command runs only if the first command is successful.
- The `node build/src/main.js` command runs the code in `src/main.ts`.

### Initialize your smart contract

To initialize your smart contract, add more code from the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file to the `src/main.ts` file.
To initialize your smart contract, add more code from the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file to the `src/main.ts` file.

All smart contracts that you create with the zkApp CLI use similar code:

Expand Down Expand Up @@ -475,9 +478,9 @@ Shutting down

### Add a transaction that fails

It's time to do some testing. To add a transaction that fails, add more code from the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file to the `src/main.ts` file.
It's time to do some testing. To add a transaction that fails, add more code from the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file to the `src/main.ts` file.

The contract logic allows the number that is stored as on-chain state to be replaced only by its square. Now that `num` is in state `9`, updating is possible only with `81`.
The contract logic allows the number that is stored as on-chain state to be replaced only by its square. Now that `num` is in state `9`, updating is possible only with `81`.

To test a failure, update the state to 75 in `zkAppInstance.update(Field(75))`:

Expand Down Expand Up @@ -569,7 +572,8 @@ Shutting down

## Follow along

You can follow along in this video as cryptographer, David Wong, learns how to code a Hello World project.
You can follow along in this video as cryptographer, David Wong, learns how to code a Hello World project.

<ResponsiveVideo src="https://www.youtube.com/embed/prx2oNpy0vo" />

The video is provided for educational purposes and uses earlier versions of the zkApp CLI and o1js, so there are some differences. The Hello World tutorial always uses the most recent version of the zkApp CLI and o1js.
Expand Down
Loading
Loading