Introduction to EVM Smart Contract development
Tags: solidity, hardhat, vyper, blockchain
Published: 2023-01-26 18:52:12

# Introduction to EVM SmartContract development

In this introduction, we will go through the basics of Hardhat, its most useful commands and a basic Hardhat workflow.

---

## Index

1. [Prerequisite](#prerequisite)
1. [Hardhat](#hardhat)
   1. [Intro](#intro)
   1. [Initial Setup](#initial-setup)
   1. [Important Commands](#important-commands)
      1. [Create local network](#create-local-network)
      1. [Compile smart contracts](#compile-smart-contracts)
      1. [Test smart contracts](#test-smart-contracts)
      1. [Deploy smart contracts](#deploy-smart-contracts)
1. [Solidity](#solidity)
   1. [About](#about)
   1. [Version](#version)
1. [Vyper](#vyper)
   1. [Solidity or Vyper](#solidity-or-vyper)
1. [Blockchain communication](#blockchain-communication)
1. [First Run](#first-run)
1. [Conclusion](#conclusion)

---

## Prerequisite

This articles starts with a few assumptions, assumptions needed to keep the scope of the article to a minimum. If you are not familiar with the following topics or you need to refresh your knowledge, I advice to take the time to read about them before continuing.

We assume that you are familiar with:
- Overall concepts and terminology of the [blockchain](https://ethereum.org/en/what-is-ethereum/)
- Comfortable using the terminal and cli tools
- Familiarity with development tools like VSCode, [TypeScript](https://www.typescriptlang.org/docs/), [Solidity](https://www.tutorialspoint.com/solidity/index.htm), [npm](https://pnpm.io/installation)

---

## Hardhat

### Intro

Hardhat is a development environment for developing on a blockchain; in our case we will focus on the Ethereum network. It provides a set of tools that makes developing smart contracts easier:

- TypeScript support
- Connect to a local network or test networks
- Run tests for your smart contracts
- Estimate costs for deploying & calling your smart contracts
- Inspect the memory slot layout of your contracts

just to name a few. It also provides an abstraction to communicate with a wallet, be it MetaMask or a hardware wallet. This way we don't need to worry about the technicalities of our wallet, we can talk directly with our smart contracts.

### Initial Setup

Hardhat is available as a NPM package and can easily be installed using your favorite package manager.

Start by initializing a new project in an empty folder:

```bash
mkdir intro
cd intro/
pnpm init
```

This will setup your project by creating a `package.json` file. To add Hardhat run the following command:

```bash
pnpm add -D hardhat
```

Once the command completes we can use `npx` to create our first Hardhat project:

```bash
npx hardhat
```

![Hardhat project layout](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewaray1t3m4vmugtg62u.png)

We will be creating a TypeScript project, simply because having the types will help us understand the data we are handling as well as save us some painful headaches. Therefore select `Create a TypeScript project` and follow the instructions.

Your project structure should look like the following
![hardhat project structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnawmeoh7ologgjusvmj.png)

The folders that matter to us in this introduction are:

- `contracts` - where we will place our smart contracts
- `scripts` - where we will place our deploy scripts (and others)
- `tests` - where we will place our tests for our smart contracts

### Important commands

With our project ready to be used, let us take some time to learn a few Hardhat commands.

#### Create local network

```bash
npx hardhat node
```

Use this command to create a local network. You are not limited by it, any network can be configured (test or mainnet)

Your local node will be setup with 10 accounts each owning 10000ETH. Hardhat will always generate the same accounts conveniently saving us from changing the account addresses in our scripts each time we launch a local node.

**NOTE: These private addresses are for testing locally and locally only! Any ETH sent to those addresses on any network (mainnet or test) will be lost!**

The process does not return, therefore my advice is to run it on a side terminal. You can even share a process across multiple projects you might be working on.

The `node` process will print information about any transaction occurring on our local blockchain, useful to check contract addresses, gas spending, etc.

**NOTE: The local network will not keep state in between runs, that is, each time this command is run will give you a fresh new blockchain.**

#### Compile smart contracts

```bash
npx hardhat compile
```

Other commands might trigger a compilation if hardhat sees any change in our smart contracts' code. Still, it is a good practice to run the compilation independently.

Upon a successful compilation, hardhat will generate nicely crafted types to use with your TypeScript code, allowing us to make use of the beautiful type system.

#### Test smart contracts

```bash
npx hardhat test
```

This command will run any test found under the `tests/` folder.

Once we configure our project, it will even be able to give us some cost estimation from deploying contracts and from calling our contract's functions.

#### Deploy smart contracts

```bash
npx hardhat run <script> --network <ethereum_network>
```

We will be using this command to deploy our smart contracts into a specified network (mostly our local network).

---

## Solidity

### About

Solidity is the programming language used to create smart contracts on the Ethereum blockchain or any blockchain compatible with the Ethereum Virtual Machine, EVM for short.

### Version

Being a programming language, it needs a compiler to convert the code into bytecode that can be understood by the EVM. Luckily, Hardhat already provides us with a compiler so no further setup is required.

You can find the current used version of the Solidity compiler in `hardhat.config.ts`

![hardhat solidity version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbhj4ah9abui48vezvk2.png)

If you wish to use a different version, simply update it in there and voila!

---

## Vyper

Vyper is another programming language used to create smart contracts on any EVM compatible blockchain. Unlike [Solidity](#solidity), Vyper is based on the python syntax. 

Hardhat does not add support for Vyper on a fresh installation. Therefore we need to explicitly add it to our dev dependencies:

```bash
pnpm add -D @nomiclabs/hardhat-vyper
```

We now need to tell hardhat to compile our Vyper contracts. Head to `hardhat.config.ts` to add a vyper import

```ts
import "@nomiclabs/hardhat-vyper";
```

This will extend the `HardhatUserConfig` to include an optional Vyper parameter to our config

```ts
const config: HardhatUserConfig = {
  // your versions may differ from mine
  solidity: "0.8.17",
  vyper: { version: "0.3.7" }
};
```

### Solidity or Vyper

Should we use one over the other? Why do we need more than one language to develop our smart contracts?

The answer to these questions will depend on multiple factors. If two programming languages offer the same set of functionality then it becomes a matter of personal choice. In our case there is a clear difference, one which is very important to know and understand how to use.

Vyper is a simpler languages restricting the logic of our smart contract. By being more strict in its features it is often cheaper to run a Vyper contract than a twin Solidity contract due to its predictability:

- Recursions are forbidden 
- No Inheritance
- No dynamic data structures

By controlling these aspects of a program, the compiler can produce more optimized code that will need less processing power to execute. Remember: less processing == less gas used (i.e. cheaper).

Because interacting with blockchains has a cost, a developer should be able to use different tools to perform the task in an optimized manner. 
- If you need complex logic: use `Solidity`
- For simple transaction based contracts: use `Vyper`

The blockchain world is still at an early age. The blockchains we know today will change, they might fade away and leave space to new, more modern, more advanced blockchains.
Programming languages will appear, based on or adapted from languages we already know and love.

What is important today might become irrelevant tomorrow. Be adaptable and curious!

---

## Blockchain communication

We are still missing an important piece to make this all work. We need a way to interact with the blockchain from our code.

The two most popular libraries at the time of writing are:

- Web3.js
- ethers.js

Hardhat provides a plugin for both, but decides to use `ethers.js` by default. Both these libraries will provide similar functionality and you can read the differences in [this article](https://medium.com/l4-media/announcing-ethers-js-a-web3-alternative-6f134fdd06f3).

---

## First run

At this point, nothing is blocking us from experimenting with what the default project provides us so far. Let’s try it!

First of all, head to the project folder. The following steps will be your usual workflow in compiling, testing and deploying.

#### Step 1

Start the local node if it isn't already running.

```bash
npx hardhat node
```

![hardhat node](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1txpoqom1hhith9bukox.png)

#### Step 2

Compile your smart contracts.

```bash
npx hardhat compile
```

![hardhat compile](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zre03wlictwdjxrcdl88.png)

#### Step 3

Test your smart contracts.

```bash
npx hardhat test
```

![hardhat test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/azirhyjzei0jrfxmxzdh.png)

#### Step 4

Deploy your smart contracts.

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

![hardhat run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ielv5vz72cl9rshlmgc8.png)

#### Step 5

Check your smart contract was added to the blockchain. Check in the terminal running the local node process for the output.

You should see something similar to the following:
![hardhat transaction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8eng45yk3tghm5ri18l.png)

This means a first block was mined (Block #1), it used 326016 GAS and our contract can be found at the (local) address `0x5fbdb2315678afecb367f032d93f642f64180aa3`

---

### Conclusion

We have covered the very basics of smart contract development.

We are able to create a Hardhat project, we learned about the essential commands that Hardhat provides and we understand the flow of developing smart contracts using Hardhat.

In the next article, we will write our first smart contract, write our first test and our first deployment script. We will also configure our hardhat project to get estimations of the cost of each of our operation on the blockchain.

Hope to see you there!