QuickNode Raises $60M Series B!
Read the Letter from our CEO.

How To Deploy a Smart Contract on Arbitrum Nova

January 18, 2023

Overview

This guide covers Arbitrum Nova, a blockchain that offers low transaction costs and high security through the AnyTrust protocol. Users will learn how to build, deploy and interact with a simple storage smart contract on Arbitrum Nova using well-known developer tools such as QuickNode and Hardhat.

What You Will Need

What You Will Do

  • Learn about the Arbitrum Nova chain
  • Build a simple storage smart contract
  • Deploy the storage contract on Arbitrum Nova
  • Interact with your deployed storage contract

What is Arbitrum Nova?

Arbitrum Nova is a blockchain offered by Arbitrum that offers ultra-low transaction costs paired with high security. The chain utilizes a technology called AnyTrust, a variation of Arbitrum Nitro technology that accepts a mild trust assumption in return for low fees to end users.

Arbitrum Nova can be advantageous for users or projects with large transaction volumes, such as game developers, social projects, and blockchain applications like NFTs, & DeFi.

Let's briefly cover how AnyTrust works.

AnyTrust Protocol

AnyTrust is a variant of Arbitrum Nitro technology, an upgrade to the "classic" Arbitrum. AnyTrust significantly reduces fees for end users by implementing a protocol called Data Availability Committee (aka DACs).

Let's now cover exactly how these trust assumptions work and how Data Availability Committees (DACs) participate in this.

Data Availability Committee (DAC)

The Data Availability Committee's goal is to ensure data availability for end users. Some of the best companies in the industry came together to form Nova's Data Availability Committee (like Google Cloud, QuickNode, and Reddit). DAC members must run the Data Availability Server (DAS) software, which consists of a Sequencer API to submit data blocks to the DAS for storage and a REST API for querying block data.

The trust assumption is that the Committee has N members, of which AnyTrust assumes at least two are honest. This means that if N-1 Committee members promise to provide access to some data, at least one of the promising parties must be honest, ensuring that the data will be available and the protocol can continue functioning.

Suppose committee members cannot provide the required data for AnyTrust to operate. In that case, the Committee loses consensus, and the Nova chain will use the Arbitrum Rollup protocol as a fallback (i.e., storing transaction data on the Ethereum chain) until the DAC committee regains consensus.

Why Arbitrum Nova?

By utilizing AnyTrust Technology and Nitro's shared codebase, Nova offers superior speed, security, and Ethereum interoperability. Transaction fees on Nova are up to 90% cheaper and faster to mine than Ethereum, all while using the same security.

Now that we have a better understanding of why one might use Arbitrum Nova, let's move on to the technical part of this guide which will demonstrate how to deploy a smart contract on Arbitrum Nova using well-known developer tools such as QuickNode and Hardhat.

Developer Set Up

Accessing Arbitrum Nova with QuickNode

You'll need an API endpoint to communicate with the Arbitrum Nova chain. You're welcome to use public nodes or deploy and manage your own infrastructure; however, if you'd like 8x faster response times, you can leave the heavy lifting to us. Sign up for a free account here.

Once signed in, click Create Endpoint and then select the Arbitrum Nova mainnet chain.



Once your endpoint is created, keep the HTTP Provider URL handy, as you'll need it in the deployment section.


Torus Wallet

There are a number of crypto wallets you can use to deploy smart contracts. For this guide, we will be using Torus Wallet, which is a non-custodial wallet that has multi-chain and network availability (e.g., Ethereum, Arbitrum One, Arbitrum Nova, and other EVM-related chains).

Note that since this guide covers the deployment on Arbitrum Nova Mainnet, you'll need real funds (aka ETH) to pay for transaction fees. However, this should be extremely cheap and should not cost more than .25 cents. ETH can be obtained on decentralized exchanges such as Uniswap or custodial exchanges such as Coinbase.

Navigate to Torus and complete the workflow to generate a private key.

Before starting the technical part of this guide, ensure you have enough funds on your Arbitrum Nova mainnet address to pay for the contract deployment and interaction.

Hardhat

Hardhat is a popular development framework for EVM-related blockchains. It consists of different components, from compiling, debugging, testing, and deploying smart contracts. You can deploy smart contracts on Hardhat using Solidity, Yul, and Assembly. You can find more information about Hardhat here.

In the next section, we will start the development of our smart contract using Hardhat.

Setting up the Project

To set up the project, we must create a folder called StorageContract and install the required dependencies.

To do this, run the following set of terminal commands:

setting up the project

Copy
mkdir StorageContract && cd StorageContract
npm init -y
npm install --save-dev hardhat
npm i dotenv
npm i @nomicfoundation/hardhat-toolbox
npx hardhat

When Hardhat prompts you on what kind of project you want to create, choose the Create an empty hardhat.config.js option.

Once the Hardhat project is created, we'll run the following set of terminal commands to create an organized development environment for our smart contract.

setting up the project

Copy
mkdir contracts
mkdir test
mkdir scripts
echo > .env

Then, we'll configure the hardhat.config.js file to have the following code:

setting up the project

Copy
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
  solidity: "0.8.17",
  networks: {
    nova: {
      url: process.env.RPC_URL,
      accounts: [process.env.PRIVATE_KEY]
    }
  }
};

Finally, open the .env file and paste the following environment variables.

setting up the project

Copy
PRIVATE_KEY=<FILLME>
RPC_URL=<FILLME>

Fill in the values with your private key and RPC URL you created in the previous section. Remember to save the file you've edited so far.

Building a Smart Contract on Arbitrum Nova

Time to get to building! If you don't have any Solidity experience already, take a moment to review the Solidity 101 section in this How to Create a "Hello World" Smart Contract with Solidity guide.

Once you're ready, create a file in your contracts folder called SimpleStorage.sol:

setting up the project

Copy
echo > contracts/SimpleStorage.sol

Open the file and input the following code:

setting up the project

Copy
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract SimpleStorage {
    address public owner;  // Public variable to store the address of the owner of the contract
    uint public value;     // Public variable to store the value

    event NewValueSet(uint value);    // Event emitted when the value is set
    event OwnerChanged(address newOwner); // Event emitted when the owner is changed

    constructor() {
        owner = msg.sender;  // Initialize the owner as the address that deployed the contract
    }

    // Modifier to check if the msg.sender is the owner before execution
    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can perform this action.");
        _;
    }

    /**
     * @dev Function to read the current value stored in the contract
     * @return uint - the value stored in the contract
     */
    function readValue() public view returns (uint) {
        return value;
    }

    /**
     * @dev Function to set a new value in the contract
     * @param _value - the new value to be set
     */
    function setValue(uint _value) public onlyOwner {
        value = _value;
        emit NewValueSet(value);
    }

    /**
     * @dev Function to read the current owner stored in the contract
     * @return address - the value stored in the contract
     */
    function getOwner() public view returns (address) {
        return owner;
    }

    /**
     * @dev Function to change the owner of the contract
     * @param _newOwner - the new owner of the contract
     */
    function changeOwner(address _newOwner) public onlyOwner {
        require(_newOwner != address(0), "The new owner address cannot be 0x0");
        owner = _newOwner;
        emit OwnerChanged(owner);
    }
}

Before moving on to the next section, take a few minutes to review the code comments to understand the storage contracts logic better. The code uses solidity concepts such as events, require statements, modifiers, and other solidity best practices.

Testing the Smart Contract Before Deployment

Before we deploy this basic storage contract, we will want to make sure the contract behaves as expected. We can do this by running some tests. In your test folder, create a file called storageTest.js with the following command:

testing the smart contract before deployment

Copy
echo > test/storageTest.js

Then, open the file in your code editor and input the following code:

testing the smart contract before deployment

Copy
const { expect } = require("chai");

describe("Storage Contract Test", function () {
    let owner;

    beforeEach(async function () {
        // Retrieve the default account from ethers
        [owner] = await ethers.getSigners();

        // A helper to get the contracts instance and deploy it locally
        const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
        simpleStorage = await SimpleStorage.deploy();
    });

    it("should set and get value correctly", async () => {
        // Set a new value
        const newValue = 12345;
        await simpleStorage.setValue(newValue);


        // Read the value and expect it to be 12345
        const value = await simpleStorage.readValue();
        expect(value).to.equal(newValue);
    });
  
    it('should return the address of the contract owner', async () => {
        // Get the owner address stored in the contract
        const contractOwner = await simpleStorage.getOwner();
  
        // Expect the contract owner to be the address that deployed the contract
        expect(contractOwner).to.equal(owner.address);
    });

    it("should change the owner correctly", async () => {
        // Change ownership to a new address
        await simpleStorage.changeOwner("0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5");
        const updatedOwner = await simpleStorage.getOwner();

        // Expect the contract owner to be the new address
        expect(updatedOwner).to.equal("0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5");
    });

});
Take a few minutes to read the code comments and understand the code

To run the test, navigate into your main directory (e.g., StorageContract) and run the following terminal command:

testing the smart contract before deployment

Copy
npx hardhat test

You should see an output similar to:

Deploying the Smart Contract on Arbitrum Nova

This section will deploy the smart contract onto Arbitrum Nova Mainnet.

In your scripts folder, create a file called deploy.js:

deploying the smart contract on arbitrum nova

Copy
echo > scripts/deploy.js

This file will contain the logic needed to deploy our contract to Arbitrum Nova Mainnet. Open the file and input the following code:

deploying the smart contract on arbitrum nova

Copy
const hre = require("hardhat");

async function deploy() {
    // Deploy the contract
    const SimpleStorage = await hre.ethers.getContractFactory("SimpleStorage");
    const simpleStorage = await SimpleStorage.deploy();

    // Print the deployed contracts address
    console.log("SimpleStorage contract deployed at:", simpleStorage.address);
}

deploy()
    .then(() => console.log("Deployment complete"))
    .catch((error) => console.error("Error deploying contract:", error));

To deploy the contract, run the following hardhat command in your terminal:

deploying the smart contract on arbitrum nova

Copy
npx hardhat run --network nova scripts/deploy.js

You should see an output that contains your deployed contract address.

Interacting with the Smart Contract on Arbitrum Nova

Navigate to Arbitrum Nova's block explorer to verify that the smart contract was deployed by putting in the address returned from the deployment script above.

To interact with the Storage contract, create an additional script within your scripts directory called interactStorage.js:

interacting with the smart contract on arbitrum nova

Copy
echo > scripts/interactStorage.js

Then open the file and input the following code:

interacting with the smart contract on arbitrum nova

Copy
const hre = require("hardhat");

async function main() {
    // Get contract factory for the SimpleStorage contract
    const SimpleStorage = await ethers.getContractFactory("SimpleStorage");

    // Attach to deployed contract at the specified address
    const simpleStorage = await SimpleStorage.attach(
      "DEPLOYED_CONTRACT_ADDRESS" // Your deployed contract address
    );
    
    // Call the readValue function to get the current value
    let getValue = await simpleStorage.readValue();
    console.log("currentValue: ", getValue)

    // Call the setValue function to update the value
    let setValueTx = await simpleStorage.setValue(420)
    console.log("setValue function call. Waiting for confirmation...")

    // Wait 3 blocks for the transaction to be confirmed
    await setValueTx.wait(confirm=3);
    
    // Call the readValue function again to get the latest value
    let latestValue = await simpleStorage.readValue();
    console.log("latestValue: ", latestValue)
}

// Start the script and handle any errors
main()
    .then(() => console.log("Script complete"))
    .catch((error) => console.error("Error running script:", error));

The script above will test setting a value in our storage contract by calling the setValue function. It will also call the readValue function to get the current value in storage. To run the script, use the following hardhat command:

interacting with the smart contract on arbitrum nova

Copy
npx hardhat run --network nova scripts/interactStorage.js

That's it! You have just created a smart contract on Arbitrum Nova using Hardhat and QuickNode!

Arbitrum Ecosystem

Now that you have deployed your first smart contract on Arbitrum Nova, you could explore some of the resources the Arbitrum Nova chain offers:

Additional Resources

If you want to continue learning about Arbitrum Nova and smart contracts, check out these resources:

Final Thoughts

Congrats! You now understand more about Arbitrum Nova and how to deploy smart contracts! What are you using Arbitrum Nova for? We'd love to see what you're creating! Share your app with us on Discord or Twitter. If you have any feedback or questions on this guide, we’d love to hear from you!

Related articles 30

Solidity vs Vyper
Published: Aug 18, 2021
Updated: Sep 23, 2022

With the introduction to smart contracts on the Ethereum blockchain, it was only a matter of time until a language other than Solidity was made to write smart contract code. Vyper is one such...

Continue reading
How to Create a BEP20 Token
Published: Jul 3, 2021
Updated: Sep 23, 2022

BEP20 is the Binance Smart Chain equivalent to the popular ERC20 specification for tokens on the Ethereum network. The difference is the BEP20 Token isn't run on the Ethereum Network, but the...

Continue reading
What is an ABI?
Published: Mar 20, 2021
Updated: Jan 13, 2023

If you prefer to watch a video walkthrough of this tutorial instead, click the link below! [yt:xamI-lHOufM]While interacting with a smart...

Continue reading
How to Create and Deploy an ERC-1155 NFT
Published: Mar 14, 2022
Updated: Sep 23, 2022

ERC1155 has emerged as a gold standard to create NFTs; every major marketplace lists new tokens as an ERC1155 standard. In this guide, we will learn about the ERC1155 token standard and how to...

Continue reading
Como crear un Token BEP20
Published: Jan 10, 2022
Updated: Sep 23, 2022

BEP20 es en Binance Smart Chain el equivalente al popular token ERC20 de la red de Ethereum. La diferencia es que el token BEP20 no corre en la red de Ethereum sino en la red de Binance Smart...

Continue reading