Welcome to this comprehensive guide on deploying your first smart contract on an EVM-compatible blockchain network. A smart contract is a self-executing piece of code stored on the blockchain, where the contract’s terms are directly written into code. This means that when the predefined conditions are met, the contract automatically executes without the need for intermediaries, ensuring secure, transparent, and trustless interactions.

In this tutorial, you’ll learn how to craft a smart contract using the Solidity language and deploy using Remix IDE or Hardhat. By understanding the inner workings of these contracts and how they operate on a decentralized network, you’ll be well-equipped to build robust and efficient applications. By the end of this guide, you’ll have developed a fully functional smart contract, ready for deployment on the peaq network.

Prerequisites

  • You have basic programming knowledge (JavaScript is a plus)
  • You have MetaMask wallet installed
  • You have access to Remix
  • You have access to a code editor like Visual Studio Code
  • Hardhat installed (for local development)
  • Node.js is installed
  • Python is installed

Instructions

The most simple way to write a smart contract is through the web-based IDE (Integrated Development Environment) called Remix. The software has been specifically tailored to the writing, development, and deployment of Solidity contracts. It contains certain features such as smart contract compilation and interaction with previously deployed contracts. Remix is the perfect platform for quick plug and play to get started with blockchain development.

1. Open Remix IDE

Head over to the Remix webpage.

2. Create a new File

In the left-hand file explorer panel, click on the New File icon to generate a new file where the smart contract code will be written. Name the file SimpleStorage.sol (.sol being the standard extension for Solidity code).

3. Write the Code

Here we will create a simple contract that stores and retrieves a number. Please copy and paste the following code in the file that you just created.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 private data;

    function set(uint256 _data) public {
        data = _data;
    }

    function get() public view returns (uint256) {
        return data;
    }
}

Understanding the code

1. File License Declaration: // SPDX-License-Identifier: MIT

  • Specifies the license under which the code is distributed, in this case MIT. It is important for open-source compliance and avoids compilation warnings.

2. Pragma Directive: pragma solidity ^0.8.0;

  • Specifies the version of solidity that is required for the code. The ^ symbol indicates compatibility with versions 0.8.0 and above (up to but not including 0.9.0).

3. Contract Declaration: contract SimpleStorage { … }

  • A contract is similar to a class in typical object oriented programming paradigms. It encapsulates state variables and functions. The contract name SimpleStorage is defined by the user and should represent its purpose.

4. State Variable: uint256 private data;

  • State variables are stored directly on the blockchain, allowing for persistence and global access. uint256 represents the variable type. In this particular case it is an unsigned integer that can hold large non-negative numbers. The identifier private restricts the access of the variable within the contract only.

5. Set Function function set(uint256 _data) public { … }

  • Functions are used in Solidity to interact with the contact. The set function here allows users to update the value of data. The keyword public means that the function is accessible to everyone (any address can call it). The keyword parameter _data is used to represent the data a user sent to the contact. By convention these variables start with an underscore.

6. Get Function function get() public view returns (uint256) { … }

  • Getter function that returns the value of the variable data that is stored on the blockchain. The keyword view is used to restrict the function to be read-only so it does not modify the state of the chain. returns specifies what type of value the function will return to the user.

With that example, we now have a simple contract that stores an integer on a blockchain. For more complex examples and explanations what you can do with the Solidity programming language please look at their documentation.

The following two sections will show you how to setup a local JavaScript and Python environment to write smart contracts. The deployment and interaction of the written contract is done in the subsequent sections.

Write your first Smart Contract with Hardhat

Remix is not the only tool you can use to deploy your smart contracts. A popular tool used in local Ethereum development is Hardhat. It allows for the development, compilation, and interaction of smart contracts on a local IDE. Similar to Remix in many ways, Hardhat does allow for more flexibility and configurability. If you would like to learn more please read about Hardhat.

Install & Initialize Hardhat

1. Install Hardhat

  • Create a New Repository and Install Hardhat:
    • Open your terminal and navigate to your project directory.
    • Run the following command to install Hardhat:
    npm install --save-dev hardhat
    

2. Initialize Hardhat

  • Initialize a new Hardhat project using:
npx hardhat init
  • Select Create an empty hardhat.config.js when prompted.

3. Install Hardhat Toolbox

  • Install the toolbox dependency for testing, contract interaction, and deployment:
npm install @nomicfoundation/hardhat-toolbox

4. Set Up Project Structure

  • Organize your project with the following standard folder structure:
project-directory/

├── contracts/             # Solidity files (e.g., SimpleStorage.sol)
├── ignition/modules/      # Deployment scripts
├── node_modules/          # Installed dependencies
├── scripts/               # Interaction scripts
├── .gitignore             # Files to exclude from Git
├── hardhat.config.js      # Hardhat configuration file
├── package.json           # Node.js project configuration
├── package-lock.json      # Dependency lock file
└── .env                   # Environment variables (created in the next step)

Configure .env and Hardhat

1. Create .env File

  • In the root directory, create a .env file to store sensitive data.
  • Install dotenv to enable environment variable support:
npm install dotenv
  • Add the following variables to the .env file:
RPC_URL="rpc_url"
PRIVATE_KEY="wallet_private_key"
  • Replace rpc_url with the RPC URL of the peaq/agung test network.
  • Replace wallet_private_key with your wallet’s private key.

2. Update hardhat.config.js

  • Update the hardhat.config.js file to include the network configuration
  • Networks added here are used in the deployment script so it knows what chain to send the bytecode to. The example below shows the test network agung.
require("@nomicfoundation/hardhat-toolbox");
require('dotenv').config();

const RPC_URL = process.env.RPC_URL;
const PRIVATE_KEY = process.env.PRIVATE_KEY;

module.exports = {
  solidity: "0.8.28",
  networks: {
    agung: {
      url: RPC_URL,
      chainId: 9990, // for agung
      accounts: [`0x${PRIVATE_KEY}`],
    },
  },
};

Create the SimpleStorage Smart Contract

Write the Contract

  • Inside the contracts/ folder, create a file named SimpleStorage.sol.
  • Copy the same code used above in the Remix contract and paste it into this newly created file:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 private data;

    function set(uint256 _data) public {
        data = _data;
    }

    function get() public view returns (uint256) {
        return data;
    }
}

You have successfully created 2 separate environments that were used to write a smart contract. Please follow the next pages to see how to deploy and interact with the contract written on this page.