# Deploy using Hardhat

[Hardhat](https://hardhat.org) is a development environment for Ethereum software. It consists of different components for editing, compiling, debugging and deploying your smart contracts and dApps, all of which work together to create a complete development environment.

## Before you Begin

* Check if you are using the right [network configuration](https://docs.plume.org/plume/network-information#network-details)
* Have enough test tokens in your wallet

{% hint style="info" %}
Learn more about claiming test tokens from [here](https://docs.plume.org/plume/developers/how-to-guides/how-to-connect-to-network/claim-test-tokens).
{% endhint %}

## Hardhat Setup

Start by creating a folder `plume-hardhat`. Open a terminal pointing to this folder and run the below command to initialize a node.js project.

```sh
npm init -y
```

Followed by installing hardhat and other necessary libraries using the below command.

```sh
npm install --save-dev hardhat @openzeppelin/contracts @nomicfoundation/hardhat-ignition-ethers dotenv
```

Let's create a hardhat project using `npx hardhat init`  now. We are using a JavaScript template from the list of options to facilitate the deployment and choosing the configuration for the project as shown below.

```
√ What do you want to do? · Create a JavaScript project
√ Hardhat project root: · \Users\...\plume-hardhat
√ Do you want to add a .gitignore? (Y/n) · y
√ Do you want to install this sample project's dependencies with npm (@nomicfoundation/hardhat-toolbox)? (Y/n) · y
```

{% hint style="info" %}
Learn more about setting up hardhat project [here](https://hardhat.org/hardhat-runner/docs/guides/project-setup).
{% endhint %}

## Configure and prepping to deploy

Let's create a `.env`  file to store the private key inside it safely.

```sh
touch .env
echo "PRIVATE_KEY=<your-wallet-private-key>" >> .env
```

Make the following adjustments to the auto-generated `hardhat.config.js` file to prepare to deploy to the **Plume Testnet** for instance (switch the RPC and verifier URL to Mainnet to deploy on Plume Mainnet):

* Import the `hardhat-toolbox` and `hardhat-ignition-ethers` plugin into the Hardhat Runtime Environment.
* Add the Plume Testnet [network details](https://docs.plume.org/plume/network-information#testnet-details).

{% code title="hardhat.config.js" overflow="wrap" %}

```javascript
require("@nomicfoundation/hardhat-toolbox");
require("@nomicfoundation/hardhat-ignition-ethers");
require('dotenv').config();

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.28",
  settings: {
    evmVersion: "cancun"
  },
  networks: {
    hardhat: {},
    "plume-testnet": {
      url: "https://testnet-rpc.plume.org",
      chainId: 98867,
      accounts: [process.env.PRIVATE_KEY]
    }
  },
  etherscan: {
    apiKey: {
      "plume-testnet": "testnet"
    },
    customChains: [
      {
        network: "plume-testnet",
        chainId: 98867,
        urls: {
          apiURL: "https://testnet-explorer.plume.org/api",
          browserURL: "https://testnet-explorer.plume.org"
        }
      }
    ]
  }
};
```

{% endcode %}

## Compile and Deploy

We'll be using a sample contract, you can replace this with your own codebase. Make sure you place the contract in **"Contracts"** directory within your Hardhat project.

<details>

<summary>Sample Smart Contract Code</summary>

This is a sample NFT contract based on [OpenZeppelin's open-source ERC-721](https://docs.openzeppelin.com/contracts/4.x/erc721) implementation to tokenize our CBO's prized Rolex watch on Plume.

{% code title="Contracts/RolexYachtMaster40.sol" %}

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract RolexYachtMaster40 is Ownable, ERC721 {
    error NFTAlreadyMinted();
    bool private _minted;

    constructor() Ownable(msg.sender) ERC721("Rolex Yacht-Master 40", "") {}

    function mint() public onlyOwner returns (uint256) {
        if (_minted) {
            revert NFTAlreadyMinted();
        }
        _safeMint(owner(), 0);
        _minted = true;
        return 0;
    }
}
```

{% endcode %}

</details>

Compile the contract(s) using the below command:

```sh
npx hardhat compile
```

Let's create a ignition module to deploy the contract(s). Create a file as `<Your-Contract>.js` at `ignition/modules/<Your-Contract>.js` . Here's a sample module we used with the above sample contract.

{% code title="RolexYachtMaster40.js" overflow="wrap" %}

```javascript
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");

module.exports = buildModule("DeployRolexYachtMaster40", (m) => {
    const RolexYachtMaster40 = m.contract("RolexYachtMaster40", [
        /** constructor args */
    ]);

    return { RolexYachtMaster40 };
});
```

{% endcode %}

Deploy your contract(s) to the Plume Testnet using the following command:

```
npx hardhat ignition deploy ./ignition/modules/<Your-Contract>.js --network plume-testnet
```

{% hint style="info" %}
To verify your contract while deploying, add a `--verify` flag in the command or go to [verify-using-hardhat](https://docs.plume.org/plume/developers/how-to-guides/how-to-verify-smart-contracts/verify-using-hardhat "mention") to learn more about post-verification steps.
{% endhint %}

### Sample Output

```
√ Confirm deploy to network plume-testnet (98867)? ... yes
Hardhat Ignition 🚀

Deploying [ DeployRolexYachtMaster40 ]

Batch #1
  Executed DeployRolexYachtMaster40#RolexYachtMaster40

[ DeployRolexYachtMaster40 ] successfully deployed 🚀

Deployed Addresses

DeployRolexYachtMaster40#RolexYachtMaster40 - 0x0c14F7df7f2B0c6F55851610849BA09f97732C9B
```

You can view the deployed contract on the [Plume Testnet Explorer](http://testnet-explorer.plume.org).
