DEV Community

Cover image for How to Build on Linea - a zk-rollup on Ethereum
Michael Bogan
Michael Bogan

Posted on

How to Build on Linea - a zk-rollup on Ethereum

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, 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, MetaMask, and Truffle: 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, 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 to existing tools.

Image description

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.

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.

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

Image description

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 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

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

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.

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

$ node -v
Enter fullscreen mode Exit fullscreen mode

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. Once you’ve created your account, navigate to the dashboard and select Create New Key.

Image description

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

$ npx truffle init
Enter fullscreen mode Exit fullscreen mode

To check if everything works properly, run:

$ npx truffle test
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

$ npm install dotenv
Enter fullscreen mode Exit fullscreen mode

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 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;
Enter fullscreen mode Exit fullscreen mode

Make sure the contract is compiling correctly by running:

npx truffle compile
Enter fullscreen mode Exit fullscreen mode

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>"
Enter fullscreen mode Exit fullscreen mode

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:

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

module.exports = {
  networks: {
    development: {
      host: "",
      port: 8545,
      network_id: "*"
    linea: {
      provider: () => new HDWalletProvider(MNEMONIC, ``),
      network_id: '59140',
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

truffle migrate --network linea
Enter fullscreen mode Exit fullscreen mode

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)


   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

> Total deployments:   1
> Final cost:          0.004261517511932249 ETH
Enter fullscreen mode Exit fullscreen mode

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

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. There are lots of use cases you can explore, including NFTs, DeFi, decentralized exchanges, and more. Have fun!

Top comments (1)

andrewg profile image
Andrew Gross

Nice easy to follow article! I think a final step that is often skipped but important is to verify the token contract on the Blockscout explorer once it is deployed. It provides more transparency and legitimacy to the token/contract.