How To Build on Linea: A ZK-rollup on Ethereum
In this tutorial, let's deploy a smart contract on Linea, the new Ethereum L2 ZK-rollup, and learn about fast transactions using zero-knowledge proofs.
Join the DZone community and get the full member experience.
Join For FreeThere 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 transactions. Among this new set of layer two solutions, ZK-rollups (or zero-knowledge rollups) have risen to the top.
In this article, we’ll explore one of those solutions: Linea, launched by ConsenSys. 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.
Let’s get started.
What Is Linea?
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, ConsenSys recently launched Linea, a public testnet for its zkEVM chain. Linea is a developer-first ZK-rollup, focused on not only delivering zkEVM, but doing it in a way that supports developers with native integrations to existing tools.
Create Your Own Currency 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 in 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 the 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.
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.
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.
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
If all goes well, you should see a version number for the 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 an Infura free account. Once you’ve created your account, navigate to the dashboard and select Create New Key.
For the 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 the 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 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 an 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 the 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 see your token's correct balance in the Assets tab.
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 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 as an L2 gave us much-improved speed and low gas fees over the main chain- 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 Linea documentation. There are lots of use cases you can explore, including NFTs, DeFi, decentralized exchanges, and more. Have fun!
Published at DZone with permission of Michael Bogan. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments