Introduction to EVM Smart Contract development
Duarte Roso
Posted on January 26, 2023
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
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
This will setup your project by creating a package.json
file. To add Hardhat run the following command:
pnpm add -D hardhat
Once the command completes we can use npx
to create our first Hardhat project:
npx hardhat
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
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
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
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
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>
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
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
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";
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" }
};
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
Step 2
Compile your smart contracts.
npx hardhat compile
Step 3
Test your smart contracts.
npx hardhat test
Step 4
Deploy your smart contracts.
npx hardhat run scripts/deploy.ts --network localhost
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:
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!
Posted on January 26, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.