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

📝 Adding Steps for 09-recurssion tutorial #763

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
324 changes: 274 additions & 50 deletions docs/zkapps/tutorials/09-recursion.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,86 +56,310 @@ You build recursive zkApps with [ZkProgram](/zkapps/o1js-reference/modules/Exper

Proofs generated using a ZkProgram can be passed into zkApp smart contracts for them to verify recursively. They can even be passed recursively into their own functions for off-chain recursive composition.

The following ZkProgram example code is provided in the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/main.ts) example file.
The full source code for the following ZkProgram tutorial is provided in the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/main.ts) directory on GitHub. While you're there, give the `/docs2` repository a star so that other zk developers can learn to build a zkApp!

To create a ZkProgram, start with the `init()` method.
:::info
Copy link
Contributor

Choose a reason for hiding this comment

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

@LuffySama-Dev we are removing line numbers for future, so we can omit this part


- For each method, declare the inputs it will receive.
- The first argument of a ZkProgram method is always the state of the ZkProgram, named `publicInput` since it is public.
To prevent copying line numbers and command prompts as shown in the examples, use the copy code to clipboard button that appears at the top right of the snippet box when you hover over it.

```typescript
const Add = ZkProgram({
name: 'add-example',
publicInput: Field,
:::

methods: {
init: {
privateInputs: [],
## Prerequisites

Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials.

In particular, make sure you have the zkApp CLI installed:

```sh
$ npm install -g zkapp-cli
```

## Create a new project

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 09-recursion
```

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!
Comment on lines +88 to +111
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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!
The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`.

Copy link
Contributor

Choose a reason for hiding this comment

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

since this is tutorial 9, we can leave out the very detailed steps since devs will have already mastered these steps in earlier tutorials


method(state: Field) {
state.assertEquals(Field(0));
},
},
Next steps:
cd 09-recursion
git remote add origin <your-repo-url>
git push -u origin main
```

The `zk project` command creates the `09-recursion` 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.
Comment on lines +113 to +119
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Next steps:
cd 09-recursion
git remote add origin <your-repo-url>
git push -u origin main
```
The `zk project` command creates the `09-recursion` 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.
As you learned in earlier tutorials, the `zk project` command creates the `09-recursion` directory that contains the scaffolding for your project.


1. Change into the `09-recursion` directory and list the contents:

```sh
$ cd 09-recursion
$ 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 `09-recursion` 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.
Comment on lines +121 to +146
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
1. Change into the `09-recursion` directory and list the contents:
```sh
$ cd 09-recursion
$ 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 `09-recursion` 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.
1. Change into the `09-recursion` directory. Like all projects, you run commands from the root of the `09-recursion` 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.


### Prepare the project

Start by deleting the default files that come with the new project.
Copy link
Contributor

@barriebyron barriebyron Nov 29, 2023

Choose a reason for hiding this comment

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

Suggested change
Start by deleting the default files that come with the new project.
Like earlier tutorials, you can prepare your project by deleting the default files that come with the new project and creating new files.


1. To delete the old files:

```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/Add
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

@LuffySama-Dev LuffySama-Dev Jan 16, 2024

Choose a reason for hiding this comment

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

Hi @barriebyron ,

I went through all the files and I am not sure why Square.ts is used here. Code inside this file does not aligns to what tutorial is actually for.
According to me we can remove it, if possible can we ask someone from team to review it ?

Same is for zkProgram_wrapper.ts.

Can you please help to get it reviewed so I can remove it in coming commits ?

Thanks Luffy 😃

Copy link
Contributor Author

@LuffySama-Dev LuffySama-Dev Jan 16, 2024

Choose a reason for hiding this comment

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

About Add.ts I will change it back to main.ts same as previous one.

$ touch src/main.ts
```

- The `zk file` command created the `src/Add.ts` and `src/Add.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.

Comment on lines +152 to +171
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
1. To delete the old files:
```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/Add
$ touch src/main.ts
```
- The `zk file` command created the `src/Add.ts` and `src/Add.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.

Copy link
Contributor

Choose a reason for hiding this comment

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

we'll omit these steps since devs will already have experience

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

```ts src/index.ts
1 import { Add } from './Add.js';
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure where we're going with this step, are you replacing https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/Square.ts with Add.ts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, actually Square.ts was never used in tutorial. The fils which was used is main.ts. The code which we are explaining in this tutorial is about recursion and it matches the code from main.ts and not the Square.ts.

2
3 export { Add };
```

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.
Comment on lines +172 to +180
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
3. Now, open `src/index.ts` in a text editor and change it to look like:
```ts src/index.ts
1 import { Add } from './Add.js';
2
3 export { Add };
```
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.
Open `src/index.ts` in a text editor and import the Add smart contract, like:
```ts src/index.ts
import { Add } from './Add.js';
export { Add };

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

Copy link
Contributor

Choose a reason for hiding this comment

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

be sure the contract example file and all references align


## Write the ZkProgram

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

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

Choose a reason for hiding this comment

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

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

Copy link
Contributor

Choose a reason for hiding this comment

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

can you help me understand why we need the Add.ts file from tutorial 1?

Copy link
Contributor

Choose a reason for hiding this comment

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

you'll see my earlier questions, all related. Thank you for this work!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @barriebyron ,

I wen through the existing tutorial and found that we are actually showing recursion example for the Addition. In the current tutorial and it's example we are using main.ts as our main file and all the code it.

Now in earlier tutorials if you will see we were following pattern like there is a SmartContractfiles.ts which contains the smartcontract code and main.ts which includes code to interact with the SmarContractfile.ts.

This tutorial doesn't seem to be following this and might cause confusion for the developer. To avoid whole confusion I am trying to bring everything in the same pattern.

For example : In this tutorial itself you can see the Vote smartcontract has file name Vote.ts and same for Rollup smartcontract i.e Rollup.ts.

So, I am naming the Add smartcontract file as Add.ts for ease of understanding.

And coming to the file from tutorial 1, I did not review which tutorial it was taking file from. It does not have anything to do with tutorial 1.

I will fix this and update it in my upcoming commits.

Thanks Luffy 😃


This part of the tutorial walks you through the Add ZkProgram code already completed in the `src/Add.ts` example file.

### Copy the example

This tutorial describes each part of the completed code in the [Add.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Add.ts) example file.
Comment on lines +188 to +192
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
This part of the tutorial walks you through the Add ZkProgram code already completed in the `src/Add.ts` example file.
### Copy the example
This tutorial describes each part of the completed code in the [Add.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Add.ts) example file.
### Copy the example
Use the Add code already completed in the [Add.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Add.ts) example file.

Copy link
Contributor

@barriebyron barriebyron Nov 29, 2023

Choose a reason for hiding this comment

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

you can verify all example files and doc references are in sync for https://github.com/o1-labs/docs2/tree/main/examples/zkapps/09-recursion/src directory


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

1. Copy the entire contents of the file into your ZkProgram in the `src/Add.ts` file.

Now you are ready to review the imports in the ZkProgram.
Comment on lines +194 to +198
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
1. First, open the [Add.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Add.ts) example file.
1. Copy the entire contents of the file into your ZkProgram in the `src/Add.ts` file.
Now you are ready to review the imports in the ZkProgram.
1. First, open the [Add.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Add.ts) example file.
1. Copy the file's entire contents into your project `src/Add.ts` file.


### Imports

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

:::info

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

:::info

```ts src/Add.ts
1 import { Field, SelfProof, ZkProgram } from 'o1js';
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
1 import { Field, SelfProof, ZkProgram } from 'o1js';
import { Field, SelfProof, ZkProgram } from 'o1js';

```

These items are:

- `Field`: The native number type in o1js. You can think of Field elements as unsigned integers. Field elements are the most basic type in o1js. All other o1js-compatible types are built on top of Field elements.
Copy link
Contributor

Choose a reason for hiding this comment

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

do you want to describe SelfProof?

- `ZkProgram`: The o1js general purpose API for creating zero knowledge proofs. A ZkProgram is similar to zkApp smart contracts but isn't tied to an on-chain account.

### ZkProgram

To create a ZkProgram, start with the `init()` method.

- For each method, declare the inputs it will receive.
- The first argument of a ZkProgram method is always the state of the ZkProgram, named `publicInput` since it is public.

```typescript
Copy link
Contributor

Choose a reason for hiding this comment

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

let's remove the line numbers, easiest to copy code right from the example file

3 export const Add = ZkProgram({
4 name: 'add-example',
5 publicInput: Field,
6
7 methods: {
8 init: {
9 privateInputs: [],
10
11 method(state: Field) {
12 state.assertEquals(Field(0));
13 },
14 },
15 },
16 });
17
```

Add another method that takes an existing proof, adds a new number to it, and produces a new proof:

```typescript
addNumber: {
privateInputs: [SelfProof, Field ],

method(newState: Field, earlierProof: SelfProof<Field>, numberToAdd: Field) {
earlierProof.verify();
newState.assertEquals(earlierProof.publicInput.add(numberToAdd));
},
},
15
Copy link
Contributor

Choose a reason for hiding this comment

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

remove line numbers here too

16 addNumber: {
17 privateInputs: [SelfProof, Field],
18
19 method(
20 newState: Field,
21 earlierProof: SelfProof<Field, void>,
22 numberToAdd: Field
23 ) {
24 earlierProof.verify();
25 newState.assertEquals(earlierProof.publicInput.add(numberToAdd));
26 },
27 },
28 },
29 });
```

Use recursion to combine two proofs:

```typescript
add: {
privateInputs: [ SelfProof, SelfProof ],

method(
newState: Field,
earlierProof1: SelfProof<Field>,
earlierProof2: SelfProof<Field>,
) {
earlierProof1.verify();
earlierProof2.verify();
newState.assertEquals(earlierProof1.publicInput.add(earlierProof2.publicInput));
},
},
28
Copy link
Contributor

Choose a reason for hiding this comment

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

remove line numbers here too

29 add: {
30 privateInputs: [SelfProof, SelfProof],
31
32 method(
33 newState: Field,
34 earlierProof1: SelfProof<Field, void>,
35 earlierProof2: SelfProof<Field, void>
36 ) {
37 earlierProof1.verify();
38 earlierProof2.verify();
39 newState.assertEquals(
40 earlierProof1.publicInput.add(earlierProof2.publicInput)
41 );
42 },
43 },
44 },
45 });
```

To use ZkProgram, compile it and then call methods on it:
## 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 interact with the smart contract.
Copy link
Contributor

Choose a reason for hiding this comment

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

since Tutorial 4 was the "model" for these updates, it talks about interacting with the smart contract. We can omit the UI-based steps here


### Imports

For this tutorial, the `import` statement brings in items from `o1js` 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:
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need to interact with UI (I don't think so) you can omit the interact steps


```ts src/main.ts
1 import { Add } from './Add.js';
2 import { Field, verify } from 'o1js';
```

### Call Methods

Now we will add methods to call ZkProgram:
Comment on lines +302 to +304
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
### Call Methods
Now we will add methods to call ZkProgram:
### Call Methods
Add methods to call ZkProgram:


```typescript
console.log('compiling...');
3
Copy link
Contributor

Choose a reason for hiding this comment

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

be sure the example code in https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/main.ts is current
and match here (omit line numbers please)

4 async function main() {
5 console.log('compiling...');
6
7 const { verificationKey } = await Add.compile();
8
9 console.log('making proof 0')
10
11 const proof0 = await Add.init(Field(0));
12
13 console.log('making proof 1')
14
15 const proof1 = await Add.addNumber(Field(4), proof0, Field(4));
16
17 console.log('making proof 2')
18
19 const proof2 = await Add.add(Field(4), proof1, proof0);
20
21 console.log('verifying proof 2');
22 console.log('proof 2 data', proof2.publicInput.toString());
23
24 const ok = await verify(proof2.toJSON(), verificationKey);
25 console.log('ok', ok);
26 }
27
28 main();
```

const { verificationKey } = await Add.compile();
Verification of the proof can occur off-chain using the `verify()` method. This is useful for applications where you want to prove something to an off-chain entity.

console.log('making proof 0')
### Build and run the smart contract

const proof0 = await Add.init(Field(0));
Now that the Square smart contract is complete, these commands run your project as a local blockchain.
Copy link
Contributor

@barriebyron barriebyron Nov 29, 2023

Choose a reason for hiding this comment

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

what is the contract we want to build? Square? (be sure all the file names and example files match up throughout)
https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/Square.ts

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh Sorry, I missed this one.
Will proof read it once again.

According to existing tutorial and the examples, we are building three files mainly:

  • Add.ts
  • Rollup.ts
  • Vote.ts


console.log('making proof 1')
To compile the TypeScript code into JavaScript:

Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't tested this yet... looks like you ran the code locally, thank you!

would you be up for fixing the README.md file to be accurate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes Sure,

I will do it.

const proof1 = await Add.addNumber(Field(4), proof0, Field(4));
```sh
$ npm run build
```

console.log('making proof 2')
To run the JavaScript code:

const proof2 = await Add.add(Field(4), proof1, proof0);
```sh
$ node build/src/main.js
```

console.log('verifying proof 2');
console.log('proof 2 data', proof2.publicInput.toString());
You have the option to combine these commands into one line:

const ok = await verify(proof2.toJSON(), verificationKey);
console.log('ok', ok);
```
npm run build && node build/src/main.js
```

Verification of the proof can occur off-chain using the `verify()` method. This is useful for applications where you want to prove something to an off-chain entity.
- 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`.


## Voting Example

Expand Down
Loading