How to Build on Linea - a zk-rollup on Ethereum
Tags: web3, webdev, tutorial, beginners
Published: 2023-04-07 14:03:22

There are many new L2s emerging in the web3 ecosystem with the goal of improving Ethereum’s scalability. These L2s use a variety of solutions to create layers on top of Ethereum that are faster, cheaper, and yet still benefit from the base Ethereum blockchain layer to secure the transactions. Among this new set of layer two solutions, zk-rollups (or zero-knowledge rollups) have risen to the top. [Linea](https://linea.build/), launched by ConsenSys, specifically is one of the most anticipated zk-rollup projects. 

In this article, we’ll explore what makes Linea so exciting. Then, we’ll walk through a tutorial on how to build a dapp on the Linea testnet. Finally, we’ll create our own cryptocurrency on Linea using [Solidity](https://soliditylang.org/), [MetaMask](https://metamask.io/), and [Truffle](https://trufflesuite.com/): all mature ecosystem tools that are used by blockchain developers to build dapps.

Let’s get started.

## Linea: a direct line from Ethereum’s past to its present
Zk-rollups are a layer 2 solution that greatly reduces the amount of data that needs to be stored and processed on a blockchain. Zk-rollups work by conducting computations off-chain (where it’s cheaper and faster) and creating **zero-knowledge proofs** to validate these transactions, which are then recorded on-chain on the main Ethereum network. Some of the current projects using zk-proofs include Starknet (zk-starks), Loopring (zk-snarks), Immutable X, and zkSync.

But, among the zk-rollups, the **zkEVM** is arguably the most exciting development in the world of blockchain. zkEVM combines zk-rollups with EVMs (Ethereum Virtual Machines). zkEVMs boast incredibly high throughput and super low transaction costs thanks to their rollup scaling solution. At the same time, they are **EVM-compatible** which makes it possible for Ethereum developers to use zk-rollups with the knowledge and tools they already have.

Although zkEVMs are a nascent technology, a few companies like ConsenSys have managed to make breakthroughs in the space. ConsenSys recently launched [Linea](https://linea.build/), a public testnet for its heavily anticipated zkEVM chain. Linea is a developer-first zk-rollup, focused on not only delivering the promise of zkEVM, but doing it in a way that supports a seamless developer environment with [native integrations](https://consensys.net/blog/research-development/consensys-zkevm-is-ready-for-public-testnet/) to existing tools. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wvpg0ce6011phutazhpl.png)





## Create your own cryptocurrency on the Linea zk-rollup
Let’s jump in and see how it all works by deploying a token contract on Linea. Along the way, we’ll see how cheap it is to deploy our contract and how we can take advantage of Linea’s EVM-equivalency with the knowledge and tools Ethereum developers are already familiar with.

### Step 1: Install MetaMask
The first thing we’re going to do is set up a MetaMask wallet and add the Linea test network to it. MetaMask is the world’s most popular, secure, and easy to use self-custodial wallet.

You can download the MetaMask extension for your browser [here](https://metamask.io/download/).

After you install the extension, MetaMask will set up the wallet for you. In the process, you will be given a secret phrase. Keep that safe, and under no circumstances should you make it public.

Once you’ve set up MetaMask, click on the Network tab on the top-right corner of your screen. You will see an option to show/hide test networks. 

MetaMask comes automatically configured with the Linea network. Once you turn test networks on, you should be able to see the Linea Goerli test network in the dropdown. 

### Step 2: Get Some goerliETH
In order to deploy our smart contract and interact with it, we will require some free test ETH. The first step of this process is to acquire some goerliETH on the main Goerli test network.

You can obtain this for free from the list of faucets available [here](https://faucetlink.to/goerli).

Once you fund your wallet, switch back to the Goerli test network on MetaMask. You should now see a non-zero balance.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/atp9ckryvvvx4z2tzcnj.png)







### Step 3: Bridge goerliETH to Linea
Now that we have funds on Goerli, let’s bridge them over to Linea using the Hop protocol.

Visit the Hop exchange [here ](https://goerli.hop.exchange/#/send?token=ETH&sourceNetwork=ethereum&destNetwork=linea)and connect your MetaMask wallet (using the Connect Wallet button on the upper right).

Once your wallet is connected, select the _From_ network as Goerli and the _To_ network as Linea. For this tutorial, around 0.2 ETH should be sufficient.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2cyy2wnsi8hbxu3l5muk.png)





Once you click _Send_, the bridging should take a few minutes. Once it is done, switch to the Linea network on MetaMask. You should see a non-zero balance.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ip2irt4k4ysarr61jjjf.png)



### Step 4: Install NPM and Node
Like all Ethereum dapps, we will build our project using node and npm. In case you don't have these installed on your local machine, you can do so [here](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#using-a-node-version-manager-to-install-nodejs-and-npm).

To ensure everything is working correctly, run the following command:

```
$ node -v
```


If all goes well, you should see a version number for node.

### Step 5: Sign up for an Infura account
In order to deploy our contract to the Linea network, we will require an Infura account. Infura gives us access to RPC endpoints that allow for fast, reliable, and easy access to the blockchain of our choice.

Sign up for a free account [here](https://app.infura.io/register). Once you’ve created your account, navigate to the [dashboard](https://app.infura.io/dashboard) and select _Create New Key_.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3c4q2ppn7cec2amaoklr.png)




For network, choose _Web3 API_ and name it _Linea_.

Once you click on Create, Infura will generate an API key for you, and give you RPC endpoints to Ethereum, Linea, other L2s, and non-EVM L1s (and their corresponding testnets) automatically. 

For this tutorial, we are only interested in the **Linea RPC endpoint**. This URL is of the form <>

### Step 6: Create a Node Project and install necessary packages
Let's set up an empty project repository by running the following commands:

```
$ mkdir sunshine-coin && cd sunshine-coin
$ npm init -y
```


We will be using Truffle, a world-class development environment and testing framework for EVM smart contracts, to build and deploy our cryptocurrency smart contract. Install Truffle by running:

```
$ npm install —save-dev truffle
```


We can now create a barebones Truffle project by running the following command:

```
$ npx truffle init
```


To check if everything works properly, run:

```
$ npx truffle test
```


We now have Truffle successfully configured. Now, let’s install the OpenZeppelin contracts package. This package will give us access to the ERC-20 base implementation (the standard for fungible tokens) as well as a few helpful additional functionalities.

```
$ npm install @openzeppelin/contracts
```


To allow Truffle to use our MetaMask wallet, sign transactions, and pay for gas on our behalf, we will need another package called hdwalletprovider. Install it by using the following command:

```
$ npm install –save-dev @truffle/hdwallet-provider
```


Finally, in order to keep our sensitive wallet information safe, we will use the dotenv package.

```
$ npm install dotenv
```

### Step 7: Create the “Sunshine” coin contract
Open the project repository in your favorite code editor (e.g. VS Code). In the `contracts` folder, create a new file called `SunshineCoin.sol`.

We’re going to write an ERC-20 contract that inherits default features offered by [OpenZeppelin](https://www.openzeppelin.com/) and mints 10,000 coins to the deployer (or owner) of the contract. We’ll call it “sunshine coin” just for fun!

We’re also going to implement functionality that allows a wallet to mint 100 coins for free, on a one-time basis.

Add the following code to `SunshineCoin.sol`.

```
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract SunshineCoin is Ownable, ERC20 {

    // Mapping to check if a wallet has claimed its free coins
    mapping(address => bool) public hasClaimed;

    constructor() ERC20("Sunshine COin", "SC") {
        _mint(msg.sender, 1000000 * 10 ** ERC20.decimals());
    }

    // Let owner mint tokens freely
    function mintTokens(uint _amount) public onlyOwner {
        _mint(msg.sender, _amount * 10 ** ERC20.decimals());
    }

    // Let a wallet claim 100 tokens for free
    function claimTokens() public {
        require(hasClaimed[msg.sender] == false);

        _mint(msg.sender, 100 * 10 ** ERC20.decimals());
        hasClaimed[msg.sender] = true;
    }
}
```


Make sure the contract is compiling correctly by running:

```
npx truffle compile
```


### Step 8: Update Truffle config and create a .env file
Create a new file in the project’s root directory called `.env`  and add the following contents:

```
MNEMONIC = "<Your-MetaMask-Secret-Recovery-Phrase>"
```


Next, let’s add information about our wallet, the Infura RPC endpoint, and the Linea network to our Truffle config file. Replace the contents of `truffle.config.js` with the following:


```
require('dotenv').config();
const HDWalletProvider = require('@truffle/hdwallet-provider');
const { MNEMONIC } = process.env;

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*"
    },
    linea: {
      provider: () => new HDWalletProvider(MNEMONIC, `https://rpc.goerli.linea.build/`),
      network_id: '59140',
    }
  }
};
```


### Step 9: Deploy the Contract
Let us now write a script to deploy our contract to the Linea zkEVM blockchain.

In the migrations folder, create a new file called  `1_deploy_contract.js` and add the following code:


```
// Get instance of the Sunshine Coin contract
const lineaContract = artifacts.require("SunshineCoin");

module.exports = function (deployer) {
    // Deploy the contract
    deployer.deploy(lineaContract);
};
```


 We’re all set! Deploy the contract by running the following command:

```
truffle migrate --network linea
```


If all goes well, you should see output (containing the contract address) that looks something like this:

```
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.


Starting migrations...
======================
> Network name:    'linea'
> Network id:      59140
> Block gas limit: 30000000 (0x1c9c380)


1_deploy_contract.js
====================

   Deploying 'SunshineCoin'
   ----------------------
   > transaction hash:    0x865db376d1c8de21f4a882b9c0678e419708481eda4234a8f98c4f4975ee6373
   > Blocks: 2            Seconds: 18
   > contract address:    0x64ccE52898F5d61380D2Ec8C02F2EF16F28436de
   > block number:        414030
   > block timestamp:     1680726601
   > account:             0xc361Fc33b99F88612257ac8cC2d852A5CEe0E217
   > balance:             0.185605297028804606
   > gas used:            1704607 (0x1a029f)
   > gas price:           2.500000007 gwei
   > value sent:          0 ETH
   > total cost:          0.004261517511932249 ETH

   > Saving artifacts
   -------------------------------------
   > Total cost:     0.004261517511932249 ETH

Summary
=======
> Total deployments:   1
> Final cost:          0.004261517511932249 ETH
```


Notice how incredibly cheap the deployment was! Transaction fees are minimal. Also notice that the steps we followed were almost identical to what we would’ve done if we were deploying on the Ethereum mainnet.

### Step 9: Add your token to MetaMask
As a last step, let’s add our token to MetaMask so we are able to send, receive, and view balance.

Open MetaMask, and in the assets section at the bottom, click on _import Tokens_.

Here you will be asked to add the contract address and symbol of your token. Once you do that, you should be able to see the correct balance of your token in the Assets tab.




![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ecakwus1mmqnfili1zdx.png)




### Keeping building with Linea 
Congratulations! You’ve successfully deployed a smart contract to the Linea testnet. Because Linea is EVM-equivalent, we were able to leverage the best-in-class tools already available for blockchain development. We didn’t need to learn a whole new stack to take advantage of a zk-rollup solution or to develop for Linea.

More importantly, Linea gave us **much improved speed and low gas fees** over the main chain. It’s Ethereum scaling and cryptography at its best—and it’s a massive step towards making blockchains and dapps more accessible and usable by the masses.

To learn more about Linea and to start building apps, refer to the documentation [here](https://linea.build/). There are lots of use cases you can explore, including NFTs, DeFi, decentralized exchanges, and more. Have fun!