> ## Documentation Index
> Fetch the complete documentation index at: https://docs.peaq.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Build Smart Contract

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**, **Hardhat**, or **Foundry**. 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](/peaqchain/build/getting-started/get-test-tokens#create-evm-wallet) installed
* You have access to [Remix](https://remix.ethereum.org/)
* You have access to a code editor like Visual Studio Code
* [Hardhat](https://hardhat.org/hardhat-runner/docs/getting-started) or [Foundry](https://getfoundry.sh/introduction/installation/) installed (for local development)
* [Node.js](https://nodejs.org/en/download/package-manager) is installed
* [Python](https://www.python.org/downloads/) is installed

## Remix

The most simple way to write a smart contract is through a 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](https://remix.ethereum.org/) 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.

```Solidity theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
// 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](https://docs.soliditylang.org/en/v0.8.28/).

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.

## 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](https://hardhat.org/docs).

### 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:
  ```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
  npm install --save-dev hardhat
  ```

#### 2. Initialize Hardhat

* Initialize a new Hardhat project using:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
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:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npm install @nomicfoundation/hardhat-toolbox
```

#### 4. Set Up Project Structure

* Organize your project with the following standard folder structure:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
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:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npm install dotenv
```

* Add the following variables to the `.env` file:

```jsx theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
RPC_URL="rpc_url"
PRIVATE_KEY="wallet_private_key"
```

* Replace `rpc_url` with the [RPC URL](/peaqchain/build/getting-started/connecting-to-peaq#public-rpc-urls) 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.

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
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:

```Solidity theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
// 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.

## Foundry

Prefer Foundry? Use these steps to set up, configure, and compile with Foundry on peaq/agung.

### 1. Install Foundry

* Follow the official instructions: [https://getfoundry.sh/introduction/installation/](https://getfoundry.sh/introduction/installation/)

### 2. Initialize a project

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
forge init my-project
cd my-project
```

### 3. Configure `foundry.toml`

Create or update `foundry.toml` in the project root:

```toml theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
evm_version = 'london'
```

Note: The `evm_version` is set to `london` for peaq-like networks, due to the fork used on the substrate-based network.

### 4. Add the example contract

Create `src/SimpleStorage.sol` and paste the same contract used above:

```solidity theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract SimpleStorage {
    uint256 private data;

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

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

### 5. Compile

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
forge build
```

Make sure to remove the autogenerated script that references the foundry native test contract to use the `SimpleStorage.sol` instead.
