Deploy an ERC-721 Contract on Linea using Infura and Truffle
Tags: web3, tutorial, javascript, webdev
Published: 2023-06-05 16:57:17

Ethereum has a well-known problem: Transactions are slow, expensive, and don’t scale well. L2s (layer twos) are a new generation of blockchains built on top of Ethereum to solve this problem. Among these new layer two solutions, **Linea**, a **zero knowledge rollup** (or zk rollup) is one of the most promising.

In this article, we’ll look at [Linea](https://linea.build/) and why it could be the future of L2s. We’ll walk through a tutorial that creates and deploys a smart contract to Linea. And we’ll do so by using all the industry-standard tools you probably already know for building on the Ethereum network: Infura, MetaMask, Solidity, OpenZeppelin, and Truffle. Let’s get started!

## Linea: A leading zkEVM
zkEVMs are one the most talked about technologies in web3. They solve many of the most critical problems of public blockchains: cost, speed, and scalability. zkEVMs do so by using a clever piece of cryptography and scaling technology known as the ZK rollup. [ZK-rollups](https://docs.linea.build/reference/glossary#:~:text=Zero%2Dknowledge%20rollup) use zero-knowledge proofs to allow for higher throughput and lower costs by moving heavy computations off-chain in a manner that is secure and easily verifiable.

What makes zkEVMs especially exciting is that they are EVM-compatible by default. This means you can use all the tools, contracts, and libraries created for Ethereum to work on zkEVMs as well with little to no modification. These features of low cost, high speeds, and easy use make zkEVMs _the _web3 technology to master in 2023. 

Linea is a zkEVM that is _developer-first_, meaning it was built with [native integrations](https://consensys.net/blog/research-development/consensys-zkevm-is-ready-for-public-testnet/) to existing tools. If you know the common Ethereum developer tools (MetaMask, Solidity, Infura, Truffle, etc), then you already know how to work with Linea! 

Let’s walk through how to create and deploy a smart contract on Linea.

## Deploy a Contract on Linea

### Step 1: Install a Wallet and acquire lineaETH
 
In order to deploy contracts to Linea, we will need to sign off on transactions and pay for gas fees. To do so, we will require a crypto wallet that is capable of holding the gas currency.

MetaMask is the most popular self-custodial wallet solution available in the market today. It is free, safe, and easy to use. You can [download MetaMask](https://metamask.io/download/) as an extension for your browser.

If this is your first time using MetaMask, it will prompt you through a series of steps to set up your wallet. Toward the end, MetaMask will give you the option to _secure your wallet_. Make sure you do that and save your wallet’s secret recovery phrase. We will need this in a future step.

On the top right of your MetaMask window, click on the _Network_ dropdown and toggle _Show/Hide_ test networks. Once you’ve chosen to view test networks, you should see _Linea Goerli_ in the dropdown. This is the test network for Linea (we’ll use the testnet instead of the mainnet—which isn’t yet live as of the time of this article—so that we don’t have to spend real funds on our transaction fees).

As you may have already guessed, MetaMask comes automatically configured with the Linea testnet. We don’t have to do any additional configuration.

If this is your first time using Linea, you’ll see a balance of 0 lineaETH. Let’s change this by acquiring some free ETH from the [Linea Faucet](https://www.infura.io/faucet/linea).

Once you have your lineaETH, you should see a balance that looks something like this:


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



### Step 2: Acquire an Infura Linea RPC endpoint
In order to deploy contracts to Linea, we need an RPC endpoint. Recently, Infura added support for Linea, so by [creating a free account with Infura,](https://app.infura.io/register) we’ll automatically get access to Linea RPC endpoints.

After creating an Infura account, create a new API key from the [dashboard](https://app.infura.io/dashboard).


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




For network, choose _Web3 API_. You can name the project anything you like.

Once you’ve created a key, you will be navigated to the project’s dashboard which contains a section named _Endpoints_. Here, you will find an RPC for Linea. It will be of the form <>.

Keep this URL safe. We’ll need this in a future step.

### Step 3: Install NPM and Node
In order to create a Truffle project, we need NPM and Node on our local machine. You can [download both for free](https://nodejs.org/en/download).

Once you’ve done so, check that they’ve been properly configured by running the commands below. If all goes well, you should see a version number output for each command.

```
$ node -v
$ npm -v
```

### Step 4: Create a Truffle project
After installing NPM and Node, we’re ready to create a Truffle project and install all necessary packages and libraries.

We will run a series of commands on the Terminal that will do the following things in sequence:

1. Create an empty node repository
2. Install Truffle
3. Initialize a bare-bones Truffle project
4. Install necessary packages such as dotenv, openzeppelin, and HD wallet provider.

```
$ mkdir linea-nft && cd linea-nft
$ npm init -y
$ npm install -g truffle
$ truffle init
$ npm install @openzeppelin/contracts @truffle/hdwallet-provider dotenv
```


In step 4, we install OpenZeppelin to get access to base implementations of the ERC-721 standard (that powers non-fungible tokens or NFTs). 

Dotenv is a package that helps with secret management. It will ensure that sensitive information such as our wallet’s recovery phrase is not exposed publicly.

Finally, HD wallet provider is a handy package that will allow us to integrate our MetaMask wallet into our Truffle project, and pay for gas/sign transactions seamlessly.

### Step 5: Configure the Truffle project
Before we start writing our contract, let’s configure our project to make sure it can use the MetaMask wallet we set up in an earlier step, and also make requests to the Linea testnet using the Infura RPC.

In the root folder of the project, create a new file called _.env_ and add the following contents:

```
MNEMONIC = "< YOUR METAMASK WALLET RECOVERY PHRASE >"
INFURA_RPC = “< INFURA LINEA RPC URL >”
```


This is information that we don’t want to be exposed publicly. The dotenv package will ensure this is the case with the aforementioned file.

Let’s now import these values into _truffle.config.js_ and configure it to work with Linea.

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

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*"
    },
    linea: {
      provider: () => new HDWalletProvider(MNEMONIC, INFURA_RPC),
      network_id: '59140',
    }
  },
  compilers: {
    solc: {
      version: "0.8.19",
    }
  }
};
```

### Step 6: Create the contract
We’re now in a great place to write our contract.

Our contract is extremely simple. When deployed, it mints a single NFT and assigns ownership to the wallet that deploys the contract.

Our NFT will require some metadata to be associated with it. For the sake of this tutorial, we’ll use the following metadata that represents a cute panda: 

[ipfs://QmUyZoK21qb8YknXGfDB34RTY8vMqPb6Bsj9U9iLEnyrZR](https://bafybeidctmhtpljvr63xblzkjvlyxa2iaq2tqwimzt57les4yjyyu2gefq.ipfs.dweb.link/)

Here’s what you’ll see when you view the NFT in a wallet or marketplace that supports Linea NFTs):


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



Feel free to replace this with NFT metadata of your choice. If you’re interested in understanding how to format NFT metadata, [check out the documentation](https://nftschool.dev/reference/metadata-schemas/#ethereum-and-evm-compatible-chains).

In your project’s contracts folder, create a new Solidity file called _LineaNft.sol_ and add the following code:

```
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract LineaNft is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    string private _metadataUrl;

    constructor() ERC721("Linea NFT", "LNFT") {
        
        // Set metadata of the NFT
        _metadataUrl = "ipfs://QmUyZoK21qb8YknXGfDB34RTY8vMqPb6Bsj9U9iLEnyrZR";

        // Mint NFT
        _mintNFT();
    }

    function _mintNFT() private {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(msg.sender, newItemId);
        _setTokenURI(newItemId, _metadataUrl);
    }
}
```


Let’s make sure everything is working by compiling our contract.

```
$ truffle compile
```


### Step 7: Deploy the Contract to Linea Testnet
After compiling our contract and configuring our Truffle project, we’re ready to write a deployment script that launches our contract on the Linea testnet.

In the _migrations_ folder of your project, create a new file called _1_deploy_contract.js_ and add the following code:

```
// Get instance of the Linea NFT contract
const lineaNftContract = artifacts.require("LineaNft");

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


We’re all set! Deploy the contract to Linea and mint an NFT by running the following single command:

```
$ truffle migrate -–network linea
```


If all goes well, you should see an output that looks something like this:

```
Starting migrations...
======================
> Network name:    'linea'
> Network id:      59140
> Block gas limit: 61000000 (0x3a2c940)


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

   Deploying 'LineaNft'
   --------------------
   > transaction hash:    0x528016684927c412b1761e2029e5e7d39862f3ac3716e6b214ab8c105dd144fc
   > Blocks: 2            Seconds: 17
   > contract address:    0xD5B63A037FfF90ca3a73506e9856E543dE42CAA1
   > block number:        849147
   > block timestamp:     1685960558
   > account:             0xc361Fc33b99F88612257ac8cC2d852A5CEe0E217
   > balance:             0.180090609510837606
   > gas used:            2245875 (0x2244f3)
   > gas price:           2.500000008 gwei
   > value sent:          0 ETH
   > total cost:          0.005614687517967 ETH

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

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


### Step 8: Check out contract on Linea Block Explorer
We can check out our contract on the [Linea Block Explorer](https://explorer.goerli.linea.build/). All you have to do is search for your contract’s address.

Once you’ve done that, you should be able to see details about your contract, including NFT name, symbol, transaction data, etc.

You can check out the contract I deployed when creating this project [here](https://explorer.goerli.linea.build/address/0xD5B63A037FfF90ca3a73506e9856E543dE42CAA1).


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



## Conclusion
Congratulations! You’ve successfully deployed an ERC-721 contract to Linea.

If you have experience building on the Ethereum blockchain and other EVM-compatible blockchains, you probably noticed that what we did in this tutorial was identical to what you would’ve done in your normal workflow. You can access Linea’s speed, low transaction costs, and security with your current skill set. If you can build on Ethereum, you can build on Linea.

To learn more about Linea and start building dapps, check out [the documentation](https://linea.build/).