Skip to content

Commit

Permalink
e2e test script, wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Trivo25 committed Aug 28, 2023
1 parent e4ce0a3 commit 80a5dc7
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 140 deletions.
21 changes: 0 additions & 21 deletions .github/workflows/test-tutorials.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,7 @@ jobs:
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:
Expand Down
220 changes: 112 additions & 108 deletions docs/zkapps/tutorials/01-hello-world.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ zkApp programmability is not yet available on the Mina Mainnet. You can get star

# Tutorial 1: Hello World

This Hello World tutorial helps you get started with SnarkyJS, zkApps, and programming with zero-knowledge proofs.
This Hello World tutorial helps you get started with SnarkyJS, zkApps, and programming with zero-knowledge proofs.

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
✔ 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
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,59 +135,59 @@ 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

All functions used inside a smart contract must operate on SnarkyJS compatible data types: `Field` types and other types built on top of `Field` types.
All functions used inside a smart contract must operate on SnarkyJS compatible data types: `Field` types and other types built on top of `Field` types.

:::info

Expand All @@ -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 @@ -243,7 +244,7 @@ Since you're extending `SmartContract` that has its own initialization to perfor
Then, `this.num.set(Field(3))` initializes the on-chain state `num` to a value of `3`.
You can optionally specify permissions. See [setPermissions](/zkapps/snarkyjs-reference/classes/SmartContract#setpermissions) in the SnarkyJS Reference documentation.
You can optionally specify permissions. See [setPermissions](/zkapps/snarkyjs-reference/classes/SmartContract#setpermissions) in the SnarkyJS Reference documentation.
Finally, this code adds the `update()` function:

Expand All @@ -262,40 +263,40 @@ 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).

The logic also uses the `.mul()` method for multiplication of the values stored in `Field` types. You can view all available methods in the [SnarkyJS Reference](/zkapps/snarkyjs-reference) documentation.
The logic also uses the `.mul()` method for multiplication of the values stored in `Field` types. You can view all available methods in the [SnarkyJS Reference](/zkapps/snarkyjs-reference) documentation.

You remember that functions in your smart contract must operate on SnarkyJS compatible data types: `Field` types and other types built on top of `Field` types. Because a smart contract is really a zero-knowledge circuit, functions from random NPM packages work inside a smart contract only if the functions the contract provides operate on SnarkyJS-compatible data types.

Importantly, data passed as an input to a smart contract method in SnarkyJS 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

For this tutorial, the `import` statement brings in items from `snarkyjs` that you use to interact with your smart contract.
For this tutorial, the `import` statement brings in items from `snarkyjs` that you use to interact with your smart contract.

1. Copy the following lines from [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file into the `src/main.ts` file:

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,10 +572,11 @@ 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 SnarkyJS, so there are some differences. The Hello World tutorial always uses the most recent version of the zkApp CLI and SnarkyJS.
The video is provided for educational purposes and uses earlier versions of the zkApp CLI and SnarkyJS, so there are some differences. The Hello World tutorial always uses the most recent version of the zkApp CLI and SnarkyJS.

## Conclusion

Expand Down
Loading

0 comments on commit 80a5dc7

Please sign in to comment.