DEV Community

Duarte Roso
Duarte Roso

Posted on

Introduction to EVM Smart Contract development

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
  2. Hardhat
    1. Intro
    2. Initial Setup
    3. Important Commands
      1. Create local network
      2. Compile smart contracts
      3. Test smart contracts
      4. Deploy smart contracts
  3. Solidity
    1. About
    2. Version
  4. Vyper
    1. Solidity or Vyper
  5. Blockchain communication
  6. First Run
  7. 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
  • Comfortable using the terminal and cli tools
  • Familiarity with development tools like VSCode, TypeScript, Solidity, npm

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:

mkdir intro
cd intro/
pnpm init
Enter fullscreen mode Exit fullscreen mode

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

pnpm add -D hardhat
Enter fullscreen mode Exit fullscreen mode

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

npx hardhat
Enter fullscreen mode Exit fullscreen mode

Hardhat project layout

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

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

npx hardhat node
Enter fullscreen mode Exit fullscreen mode

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

npx hardhat compile
Enter fullscreen mode Exit fullscreen mode

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

npx hardhat test
Enter fullscreen mode Exit fullscreen mode

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

npx hardhat run <script> --network <ethereum_network>
Enter fullscreen mode Exit fullscreen mode

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

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, 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:

pnpm add -D @nomiclabs/hardhat-vyper
Enter fullscreen mode Exit fullscreen mode

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

import "@nomiclabs/hardhat-vyper";
Enter fullscreen mode Exit fullscreen mode

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

const config: HardhatUserConfig = {
  // your versions may differ from mine
  solidity: "0.8.17",
  vyper: { version: "0.3.7" }
};
Enter fullscreen mode Exit fullscreen mode

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.


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.

npx hardhat node
Enter fullscreen mode Exit fullscreen mode

hardhat node

Step 2

Compile your smart contracts.

npx hardhat compile
Enter fullscreen mode Exit fullscreen mode

hardhat compile

Step 3

Test your smart contracts.

npx hardhat test
Enter fullscreen mode Exit fullscreen mode

hardhat test

Step 4

Deploy your smart contracts.

npx hardhat run scripts/deploy.ts --network localhost
Enter fullscreen mode Exit fullscreen mode

hardhat run

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

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!

Oldest comments (0)