Skip to content

Commit

Permalink
docs: add ZK chain tutorial (#36)
Browse files Browse the repository at this point in the history
* docs: add zk chain tutorial

* docs: cleanup zk chain tutorial

* Apply suggestions from code review

Co-authored-by: Sabrina <[email protected]>

* docs: add review suggestions

* docs: minor fixes and feedback

* docs: minor fixes and add feedback

* docs: apply feedback to add more context

* docs: use allowlist

* docs: address feedback

* fix: minor fixes

* Apply suggestions from code review

Co-authored-by: Sabrina <[email protected]>

* docs: address feedback

* Apply suggestions from code review

Co-authored-by: Sabrina <[email protected]>

* docs: address feedback

---------

Co-authored-by: Sabrina <[email protected]>
  • Loading branch information
sarahschwartz and itsacoyote authored Aug 15, 2024
1 parent 1ac6ea8 commit 26a9938
Show file tree
Hide file tree
Showing 6 changed files with 703 additions and 1 deletion.
277 changes: 277 additions & 0 deletions content/tutorials/custom-zk-chain/10.index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
---
title: Getting Started with ZK Chains
description: Create and run your first ZK chain.
---

This tutorial shows you how to use the `zk_inception` CLI to run an Elastic Chain ecosystem and custom ZK chain locally:

- You'll set up a local **Elastic Chain ecosystem**
- You'll create a standard **ZK chain**
- You'll deploy a smart contract to your local **ZK chain**
- You'll create a second ZK chain that uses a **custom ERC20 base token**

## Prerequisites

- Make sure your machine satisfies the [system
requirements](https://github.com/matter-labs/era-compiler-solidity/tree/main#system-requirements).
- If you aren't already familiar with deploying smart contracts on ZKsync Era, please refer to the first section of the [quickstart tutorial](https://docs.zksync.io/build/start-coding/quick-start/deploy-your-first-contract).
- For background on the Elastic Chain or ZK chains, read the [ZK chains](https://docs.zksync.io/zk-stack/concepts/zk-chains) section in our docs.
- Install the dependencies for the `zksync-era` repo by following the instructions in the matter-labs/zksync-era project's [Setup dev guide](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/setup-dev.md)
(you can skip the "Environment" section).

::callout{icon="i-heroicons-light-bulb"}
If you previously have `foundry-zksync` installed,
reinstall the normal version of [foundry](https://book.getfoundry.sh/getting-started/installation) for this tutorial.
::

## Installing `zk_inception` CLI

To install the CLI globally, run this command in your root folder.
You can use the Rust command `cargo` to install the CLI with the command below:

```bash
cargo install --git https://github.com/matter-labs/zksync-era/ \
--locked zk_inception --force
```

::callout{icon="i-heroicons-light-bulb"}
You can find a full reference for the `zk_inception` CLI in the [`zksync-era` repo](https://github.com/matter-labs/zksync-era/tree/main/zk_toolbox/crates/zk_inception).
::

## Setting up the Elastic Chain ecosystem

An Elastic Chain ecosystem is, in short, a system to manage multiple ZK chains.
The vision for the Elastic Chain is an ever-expanding network of ZK rollups, secured by math and natively interoperable under a uniform, intuitive UX.
New chains can be registered to the ecosystem to scale applications and communities as needed, making it "elastic".

There are two components needed for running a ZK chain locally:

1. An Elastic Chain ecosystem to manage different chains
2. At least one chain deployed within the ecosystem

To setup both of these components, use the `zk_inception` CLI.

The first step is to create a new ecosystem with the `ecosystem create` command.

::callout{icon="i-heroicons-light-bulb"}
Make sure Docker is running on your machine.
::

Move to a directory where you want your ecosystem folder to be, and run the command below to generate an ecosystem folder.

```bash
zk_inception ecosystem create
```

You will be prompted with a series of options to customize your ecosystem and generate a new chain within the ecosystem.
For this tutorial, use the options shown below.
If you choose different names for your ecosystem or chain, remember to update the names in the commands later on.

```bash
$ zk_inception ecosystem create

┌ ZKsync toolbox
◇ What do you want to name the ecosystem?
│ my_elastic_chain
◇ Select the origin of zksync-era repository
│ Clone for me (recommended)
◇ Select the L1 network
│ Localhost
◇ What do you want to name the chain?
│ zk_chain_1
◇ Whats the chain id?
│ 271
◇ Select how do you want to create the wallet
│ Localhost
◇ Select the prover mode
│ NoProofs
◇ Select the commit data generator mode
│ Rollup
◇ Select the base token to use
│ Eth
◇ Do you want to start containers after creating the ecosystem?
│ Yes
```

By running this command and selecting these options, you just:

- Created a new ecosystem called `my_elastic_chain`, which can contain many chains.
- Cloned the `zksync-era` repository inside the `my_elastic_chain` folder.
- Chose to use a local network to act as the L1.
This means we'll have to run a local reth node as well (don't worry, the CLI will automatically set this up and run it for you!).
We need to do this because our ecosystem contracts need to get deployed on an L1, so we can either use a local L1 chain or the Sepolia testnet.
For development purposes, it's easier to use a local L1 chain.
- Created a new chain called `zk_chain_1` and set it as your default chain.
- Set the chain id to `271`.
- Chose the default wallet configuration.
This option will use known mnemonic phrases to generate the `wallets.yaml` configuration files for the ecosystem and chain.
You can also choose `random` to randomly generate the wallets,
`empty` to generate a config file with empty values for the wallets,
or `in-file` to set the location of the config to an existing file.
- Selected to not use proofs, which makes testing more lightweight.
- Chose a standard rollup for the data availability.
You can read more about data availability options for ZK chains in the
[ZK chains](https://docs.zksync.io/zk-stack/concepts/zk-chains#data-availability-da) docs.
- Selected ETH to use as the base token.
- Started the containers for the ecosystem in Docker.

Inside the generated `my_elastic_chain` folder, you should now have the following contents:

- `ZkStack.yaml`: a configuration file for the ecosystem.
- `chains`: a folder with configurations for each chain created.
- `configs`: configuration for the deployments and wallets.
- `volumes`: dependencies for running local nodes.
- `zksync-era`: a clone of the `zksync-era` repository.
- `docker-compose.yml`: a Docker compose file to start up a local environment.

## Deploying the ecosystem

You've just set up your ecosystem and chain, and have two Docker containers running:
a postgres database for your chain, and a reth node for the local L1 chain.

The L1 chain is already running, but your ecosystem and chain aren't deployed yet.
The next step is to deploy your ecosystem contracts to the L1 and register your chain to the ecosystem.

Move into the ecosystem folder:

```bash
cd my_elastic_chain
```

Next, run the `ecosystem init` command below to deploy the ecosystem:

```bash
zk_inception ecosystem init --dev
```

The `--dev` flag will choose the default options for development.

::callout{icon="i-heroicons-light-bulb"}
If you have any issues at this step, try reinstalling the dependencies at the top.
::

This process will take some time as there is a lot happening here.
To see more detailed logs of what is happening at each step, you can add the `--verbose` flag to the command.

To summarize, the `ecosystem init` command:

- Checks to see if your environment has the necessary dependencies.
- Compiles and deploys all of the necessary contracts for the ecosystem.
- Deploys `zk_chain_1` to the ecosystem.
- Sets up a database for the default chain (in this case `zk_chain_1`).
- Deploys a paymaster contract and some test ERC20 contracts to use for development.

You can find the paymaster contract code deployed to your chain in the `zksync-era` repo in [`contracts/l2-contracts/contracts/TestnetPaymaster.sol`](https://github.com/matter-labs/era-contracts/blob/main/l2-contracts/contracts/TestnetPaymaster.sol),
and the deployed address inside `<my_elastic_chain>/chains/zk_chain_1/configs/contracts.yaml` at `l2:testnet_paymaster_addr`.

For the ERC20 contracts, you can find the deployed addresses inside `<my_elastic_chain>/configs/erc20.yaml`.

### Understanding the chain configs

Running the `init` command will also modify your chain configuration files in the ecosystem folder.

The main configuration file for `zk_chain_1` can be found in `<my_elastic_chain>/chains/zk_chain_1/ZkStack.yaml`.
It contains the most basic configurations for the chain.

Inside `<my_elastic_chain>/chains/zk_chain_1/configs`, you can find six more configuration files:

1. `contracts.yaml`: configurations for all the L1 & L2 contracts.
1. `external_node.yaml`: configurations for the chain's node server.
1. `general.yaml`: general configurations.
1. `genesis.yaml`: chain specific configurations with parameters that were used during genesis.
1. `secrets.yaml`: secrets that are individual for every chain.
1. `wallets.yaml`: all wallets that you are using for this chain.

::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
Never commit your private keys or sensitive secrets.
::

### Starting the chain server

The last step here is to start a server for `zk_chain_1`:

```bash
zk_inception server
```

With this, your L1 chain should be running at port `8545`, and the `zk_chain_1` node should be running at port `3050`.

## Funding a wallet on your chain

Because you chose to use a local reth node for your L1 and selected ETH as the base asset,
you have access to several rich wallets on the L1 that you can use to bridge ETH to `zk_chain_1`.

You can find a full list of rich wallet addresses and their private keys in the [ZKsync docs](https://docs.zksync.io/build/test-and-debug/in-memory-node#pre-configured-rich-wallets).

::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
Never use these wallets in production or send real funds to them.
::

Open a new terminal and run the command below to bridge some ETH to `zk_chain_1` using ZKsync CLI:

```bash
npx zksync-cli bridge deposit --rpc=http://localhost:3050 --l1-rpc=http://localhost:8545
```

For testing purposes, we'll use one of the rich wallets as both the sender and recipient:

```shell
? Amount to deposit 10
? Private key of the sender 0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110
? Recipient address on L2 0x36615Cf349d7F6344891B1e7CA7C72883F5dc049
```

To see that it worked, let's check the balance of that address on `zk_chain_1`:

```bash
npx zksync-cli wallet balance \
--address 0x36615Cf349d7F6344891B1e7CA7C72883F5dc049 \
--rpc http://localhost:3050
```

Now this address has ETH available on `zk_chain_1` to use for testing.

## Deploying a contract to chain 1

Now that your chain is deployed and your wallet is funded, let's create a template contract and deploy it to `zk_chain_1`:

Move out of your ecosystem folder and initialize a new hardhat project using ZKsync CLI:

```bash
npx zksync-cli@latest create --template qs-hello-zksync zk-chain-test
cd zk-chain-test
```

Use the same private key for the rich wallet:

```shell
? Private key of the wallet responsible for deploying contracts (optional)
0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110
```

In the `hardhat.config.ts` file, change the default network on line 6 to `dockerizedNode`,
which is already configured to connect to the local chain node running on port `3050`:

```bash
defaultNetwork: "dockerizedNode",
```

Finally, compile the contract and run the deploy script:

```bash
yarn compile && yarn deploy
```

Nice - you just deployed a contract to your own local ZK chain!

Next, let's take a look at customizing a chain.
Loading

0 comments on commit 26a9938

Please sign in to comment.