Smart Contracts on Ethereum - 04: Deployment πŸš€

Deploy the InteractionLogger smart contract locally and on Arbitrum Sepolia, verify it on Arbiscan, and interact with it via console and blockchain explorer UI.

Smart Contracts on Ethereum - 04: Deployment πŸš€
Photo by Tandem X Visuals / Unsplash

Welcome Back!

Previously, in Part 03: Testing you tested the InteractionLogger smart contract. Now it is time to deploy it and send real transactions. First to a local blockchain for fast iteration, and then to Arbitrum Sepolia (a public Ethereum Layer 2 testnet) so anyone can inspect and interact with it.

πŸ’‘
Assumption: You are using the same Hardhat project from the previous articles.

Table of Contents

  1. Introduction
  2. Deployment Script
  3. Local Deployment (Hardhat Network)
  4. Public Deployment (Arbitrum Sepolia)
  5. What’s Next?

1. Introduction

Deploying a smart contract means publishing its bytecode on-chain via a transaction. Once deployed, the contract gets a permanent address and can be called by anyone.

My personal proven workflow is:

  • Deploy locally for fast feedback loops
  • Deploy to a public testnet for realistic conditions (gas, explorers, wallet apps)
  • Verify the source code so others can read and interact with it

2. Deployment Script

🎯 Goal

Create a Hardhat script that deploys InteractionLogger which we will use for both deployments (local and public).

πŸ’» Code

Create the directory scripts:

mkdir -p scripts

Create the file scripts/deploy.ts and add the following code:

import { ethers } from "hardhat";

async function main() {
  const [deployer] = await ethers.getSigners();
  console.log("Deploying with:", deployer.address);

  const contract = await ethers.deployContract("InteractionLogger", []);
  await contract.waitForDeployment();

  console.log("InteractionLogger deployed to:", contract.target);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

πŸ” Breakdown

  • ethers.getSigners() returns local accounts (the first one is used as the deployer)
  • ethers.deployContract(...) deploys the smart contract
  • waitForDeployment() waits until the block where the transaction resides, is mined
  • contract.target returns the contract address

3. Local Deployment (Hardhat Network)

In this chapter you will deploy the smart contract to a local blockchain, i.e. the Hardhat Network.

3.1 Start the Local Node

🎯 Goal

Run a local blockchain that behaves like Ethereum, but resets whenever you restart it.

πŸ’» Code

Open a terminal and run:

npx hardhat node

Keep this terminal running.

πŸ” Breakdown

As an in-memory blockchain, Hardhat Network is fast and deterministic and provides funded test accounts automatically. This is perfect for local development without the hassle of acquiring testnet coins.


3.2 Deploy the Smart Contract

🎯 Goal

Deploy InteractionLogger to the local node and copy the contract address.

πŸ’» Code

Open a second terminal and run:

npx hardhat run --network localhost scripts/deploy.ts

Copy the printed contract address and save it for later use.

πŸ” Breakdown

  • --network localhost tells Hardhat to send the deployment transaction to your local node
  • Each restart of the node resets the blockchain state

3.3 Interact via Hardhat Console

🎯 Goal

Call functions on your deployed contract directly using the interactive Hardhat console.

πŸ’» Code

Start the console:

npx hardhat console --network localhost

Load the deployed contract (replace YourCopiedAddressHere with the contract address you saved above):

const contract = await ethers.getContractAt(
  "InteractionLogger",
  "YourCopiedAddressHere"
);

Write data:

await contract.setInteraction("Alice");

Read data:

await contract.getInteractionByName("Alice");

Example output:

πŸ” Breakdown

  • getContractAt(name, address) creates a contract instance pointing to an existing deployment
  • setInteraction(...) creates a transaction and sends it to the deployed contract
  • getInteractionByName(...) reads the current state

4. Public Deployment (Arbitrum Sepolia)

In this chapter, you will deploy the smart contract to a public blockchain.

Public networks usually come in two flavors: mainnets and testnets. On a mainnet, every transaction costs real money, so you need real funds in your wallet. Since we are experimenting and learning, we will deploy to a testnet instead, specifically Arbitrum Sepolia, an Ethereum Layer-2 test network.

⚠️
Never use an account with real funds for testing purposes.

4.1 Prepare Environment Variables for Secrets

🎯 Goal

Avoid hardcoding sensitive information (mnemonic, API key) and keep it out of your source code.

πŸ’» Code

Install dotenv:

npm install dotenv

Create a .env file in the project root and add the following lines:

MNEMONIC=""
ARBISCAN_API_KEY=""

πŸ” Breakdown

  • dotenv lets you read values from a .env file
  • Hardhat has already added an entry for .env in .gitignore
  • Git ignores everything listed in .gitignore, so secrets will not be committed

4.2 Set Your Mnemonic

🎯 Goal

Provide a signing account for deployment transactions.

πŸ’» Code

Set the mnemonic you have created in Part 01: Setup in .env:

MNEMONIC="word1 word2 ... word12"

πŸ” Breakdown

  • Hardhat derives accounts from the mnemonic and uses them to sign transactions.
⚠️
Again: Do NOT use an account with real funds here!

4.3 Set Your Arbiscan API Key

🎯 Goal

Create an Arbiscan API key so Hardhat can verify your contract automatically after deployment.

πŸ’» Code

  1. Go to Arbiscan, create an account, and sign in:
https://arbiscan.io/
  1. Open the API Keys page and click + Add:
Arbiscan: add API key
  1. Enter a name for the key and click Create New API Key:
Arbiscan: create API key
  1. Copy the key and paste it into your .env file:
ARBISCAN_API_KEY="YOUR_ARBISCAN_API_KEY"

πŸ” Breakdown

Hardhat uses your API key to submit contract metadata for verification, so Arbiscan can display your source code and enable the Read Contract and Write Contract tabs.


4.4 Configure Hardhat for Arbitrum Sepolia

🎯 Goal

Add Arbitrum Sepolia as a Hardhat network and configure verification via Arbiscan.

πŸ’» Code

Update hardhat.config.ts:

import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "dotenv/config";

const MNEMONIC = process.env.MNEMONIC || "";
const ARBISCAN_API_KEY = process.env.ARBISCAN_API_KEY || "";

if (!MNEMONIC) {
  throw new Error("Missing MNEMONIC in .env");
}

if (!ARBISCAN_API_KEY) {
  throw new Error("Missing ARBISCAN_API_KEY in .env");
}

const config: HardhatUserConfig = {
  solidity: "0.8.24",
  networks: {
    arbitrumSepolia: {
      url: "https://sepolia-rollup.arbitrum.io/rpc",
      chainId: 421614,
      accounts: {
        mnemonic: MNEMONIC,
        path: "m/44'/60'/0'/0",
        initialIndex: 0,
        count: 1,
      },
    },
  },
  etherscan: {
    apiKey: ARBISCAN_API_KEY,
  },
};

export default config;

πŸ” Breakdown

  • The network name arbitrumSepolia is what you will use in CLI commands
  • chainId: 421614 targets the correct Arbitrum Sepolia chain
  • etherscan.apiKey is used by Hardhat’s verification task
  • @nomicfoundation/hardhat-toolbox includes verification support

4.5 Deploy the Smart Contract

🎯 Goal

Deploy InteractionLogger to the testnet and obtain the deployed address.

πŸ’» Code

Run:

npx hardhat run --network arbitrumSepolia scripts/deploy.ts

Copy the printed contract address and save it for later use.

πŸ” Breakdown

This sends a real deployment transaction to Arbitrum Sepolia.


4.6 Check the Deployment

🎯 Goal

Locate your contract in the official Arbitrum Sepolia blockchain explorer to confirm it exists on-chain.

πŸ’» Code

  1. Open Arbiscan:
https://sepolia.arbiscan.io/
  1. Paste your saved contract address from above into the search bar and open the result:
  1. Open the Contract tab to see the details of the smart contract:

πŸ” Breakdown

Before verification, blockchain explorers typically show bytecode and transactions, but not your readable source code.


4.7 Verify the Contract on Arbiscan

🎯 Goal

Publish the source code so others can read and interact with the contract.

πŸ’» Code

Verify:

npx hardhat verify --network arbitrumSepolia YourContractAddressHere

Example output:

Refresh the Arbiscan page. You should now see the three tabs Code, Read Contract, and Write Contract:

πŸ” Breakdown

Verification links on-chain bytecode to your source code. For verification to succeed:

  • compiler version must match
  • settings must match
  • constructor args must match

4.8 Write to the Contract via Arbiscan

🎯 Goal

Call setInteraction(...) via the explorer UI using MetaMask.

πŸ’» Code

  1. Open on the Write Contract tab and click on the Connect to Web3 button:
  1. Select MetaMask:
  1. Click on the Connect button:
  1. You are now connected with your MetaMask wallet and may interact with the smart contract:
  1. Click on the setInteraction button, enter a name in the input field and click on the Write button:
  1. Click on the Confirm button in the MetaMask wallet:
  1. Click on the View your transaction button. Usually, in less than a second, the transaction will be added to a block and you will see your confirmed transaction:

πŸ” Breakdown

  • Write actions create transactions and cost gas
  • MetaMask signs the transaction and sends it to the network
  • After confirmation, your contract state is updated

4.9 Read from the Contract via Arbiscan

🎯 Goal

Read the stored interaction via the explorer.

πŸ’» Code

  1. Open the Read Contract tab:
  1. Click on the getInteractionByName button, enter the previously set name in the input field and click on the Query button:

πŸ” Breakdown

  • Read calls do not change state
  • They do not require gas and do not require transaction

5. What’s Next?

You now have a contract deployed locally (for fast iteration) and on a public testnet (for realistic conditions). That is the foundation for integrating a frontend or backend application.

In the next part, you will deploy a smart contract for managing fungible tokens.