# Hardhat Smart Contract Development

#### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* MetaMask installed & connected to a local Creditcoin node or public testnet
* A funded account
* Node.js & NPM installed

#### Setting up Hardhat <a href="#setting-up-hardhat" id="setting-up-hardhat"></a>

To create a Hardhat project you must initialize a node project using `npm`. Navigate to the folder where you want to build your project and run:

```
npx hardhat init
```

If you don’t have Hardhat installed globally, you’ll be prompted to do so.

Follow the prompts to set up your project. You can choose options like creating a sample project or starting an empty project. For this tutorial, we will crate a TypeScript project.

#### Writing your first contract <a href="#writing-your-first-contract" id="writing-your-first-contract"></a>

For this tutorial we will use a simple Counter contract.

Copy the contents of <https://github.com/gluwa/creditcoin3/blob/dev/docs/smart-contract-development/with-hardhat/contracts/Counter.sol> into `contracts/Counter.sol` inside the directory of your Hardhat project.

#### Compiling <a href="#compiling" id="compiling"></a>

Before you can deploy or test your contract you need to compile it. Run the command:

```
npx hardhat compile
```

#### Testing <a href="#testing" id="testing"></a>

Before you deploy the contract, you want to make sure it works as expected. You can use Hardhat to write and run some tests for the Counter contract. Copy the contents of <https://github.com/gluwa/creditcoin3/blob/dev/docs/smart-contract-development/with-hardhat/test/Counter.ts> into `test/Counter.ts` inside the directory of your Hardhat project.

Test the contract by running the command

```
npx hardhat test
```

You should see output similar to:

```
$ npx hardhat test

  Counter contract
    ✔ Should be deployed with the initial value 0
    ✔ Should increment count by 1

  Lock
    Deployment
      ✔ Should set the right unlockTime
      ✔ Should set the right owner
      ✔ Should receive and store the funds to lock
      ✔ Should fail if the unlockTime is not in the future
    Withdrawals
      Validations
        ✔ Should revert with the right error if called too soon
        ✔ Should revert with the right error if called from another account
        ✔ Shouldn't fail if the unlockTime has arrived and the owner calls it
      Events
        ✔ Should emit an event on withdrawals
      Transfers
        ✔ Should transfer the funds to the owner


  11 passing (492ms)

```

where *Counter contract* is the contract that you had just added and *Lock* is another contract which was automatically generated by the `hardhat init` command. To add more tests to the contract, add more `it` statements to its test file!

#### Deploying a smart contract <a href="#deploying-a-smart-contract" id="deploying-a-smart-contract"></a>

To deploy your contract, you will need to write an ignition module for Hardhat.  Copy the contents of <https://github.com/gluwa/creditcoin3/blob/dev/docs/smart-contract-development/with-hardhat/ignition/modules/Counter.ts> into `ignition/modules/Counter.ts` inside the directory of your Hardhat project!&#x20;

You can deploy the contract by running the command:

```
npx hardhat ignition deploy ignition/modules/Counter.ts --network <network-name>
```

Without the `--network` flag, the deployment will run against the local Hardhat Network, which means it gets lost after the command finishes running. But it is useful for testing that your ignition module works.

```
$ npx hardhat ignition deploy ignition/modules/Counter.ts 

You are running Hardhat Ignition against an in-process instance of Hardhat Network.
This will execute the deployment, but the results will be lost.
You can use --network <network-name> to deploy to a different network.

Hardhat Ignition 🚀

Deploying [ CounterModule ]

Batch #1
  Executed CounterModule#Counter

[ CounterModule ] successfully deployed 🚀

Deployed Addresses

CounterModule#Counter - 0x5FbDB2315678afecb367f032d93F642f64180aa3
```

To deploy the contract to a remote network, you will need to define that network inside the `hardhat.config.ts` file. See for example <https://github.com/gluwa/creditcoin3/blob/dev/docs/smart-contract-development/with-hardhat/hardhat.config.ts> and <https://github.com/gluwa/creditcoin3/blob/dev/docs/smart-contract-development/with-hardhat/hardhat-creditcoin3.config.ts>

In this example we will use Creditcoin Testnet.

{% hint style="warning" %}
Avoid at all costs hard-coding credentials into source code. Use the `vars.get` method in combination with the `vars set` Hardhat command to set them up in a safe way. You can also use environment variables prefixed with `HARDHAT_VAR_` to override the values of configuration variables. For example:

`HARDHAT_VAR_CC3TEST_PRIVATE_KEY=123...`
{% endhint %}

Once you have updated `hardhat.config.ts` you will then need to set the private key of your EVM account by running the Hardhat `vars set` command:

```
$ npx hardhat vars set CC3TEST_PRIVATE_KEY
✔ Enter value: ********************************
```

After setting up the new config, run the command:

```
npx hardhat ignition deploy ignition/modules/Counter.ts --network creditcoin_testnet
```

#### More information

Please refer to the official documentation of Hardhat at <https://hardhat.org/tutorial> for more information.
