The modern world of web development is growing every day, and almost every day, new technologies simplify development. As they say, modern solutions require modern problems.
Hence, people invented web3, which allows you to create amazing applications using smart contracts with almost no effort (at least they try, and using Copilot brings this wonderful moment even closer).
In this post, we'll dive deeper into Web3 contracts and learn how to set them up using Hardhat and Node.js.
Web3 refers to a new paradigm for applications on the internet and represents the third epoch of the web.
The history of the Internet can be divided into the following epochs:
Smart contracts are a fundamental feature of Web3. They are not "smart" or "contracts" traditionally. Instead, they are programmable contracts automatically executed when predetermined conditions are met.
They operate on the blockchain, providing transparency, security, and decentralization.
There are various tools available for smart contract development, but Hardhat stands out for a few reasons:
Node.js (and JavaScript at all) is a popular runtime that allows developers to use JavaScript on the server side. For Web3 development, it can be useful because society provides a vast repository of libraries, and some of them can be used for web3 development.
A moment of bragging and self-promotion: I can write all this in the Rust language, but JS in this context is much easier to understand and reaches a broader audience.
Install Node.js and initialize project:
You need to have installed Node.js (from myself, I can recommend using nvm).
After you have prepared the environment, let's initialize the project.
mkdir dive-web3
cd dive-web3
npm init -y
Setting up Hardhat:
Install Hardhat:
npm install --save-dev hardhat
Run the Hardhat setup:
npx hardhat init
Follow the setup prompts. In my case, it will be next:
888 888 888 888 888
888 888 888 888 888
888 888 888 888 888
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
888 888 "88b 888P" d88" 888 888 "88b "88b 888
888 888 .d888888 888 888 888 888 888 .d888888 888
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
👷 Welcome to Hardhat v2.17.4 👷
✔ What do you want to do? · Create a TypeScript project
✔ Hardhat project root: · /Users/username/work/web3-dive
✔ 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
I chose TypeScript because it’s more convenient for me, but you can choose JavaScript, and IMHO nothing changes.
In the contracts
directory, create a new file named SimpleStorage.sol
:
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 private _storedValue;
function set(uint256 value) public {
_storedValue = value;
}
function get() public view returns (uint256) {
return _storedValue;
}
}
This contract simply stores a number and allows you to retrieve it.
After we finish with our contract, we need to compile it…
npx hardhat compile
And test it…
Create a test file in the test
directory, e.g., simpleStorageTest.js
:
const { expect } = require("chai");
describe("SimpleStorage", function() {
it("Should return the new value once it's changed", async function() {
const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
const simpleStorage = await SimpleStorage.deploy();
await simpleStorage.deployed();
await simpleStorage.set(23);
expect(await simpleStorage.get()).to.equal(23);
});
});
Run the test:
npx hardhat test
That's it, now we are skilled web3 developers.
First, we need to create a deploy script.
Create deploySimpleStorage.js
in scripts
directory:
import { ethers } from "hardhat";
async function main() {
const lock = await ethers.deployContract("SimpleStorage");
await lock.waitForDeployment();
console.log(`SimpleStorage deployed to ${lock.target}`);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Before you deploy your contract, you need to specify the network in hardhat.config.js
or start the hardhat node (in another tab of your terminal):
npx hardhat node
After this command, you will next see:
Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/
Accounts
========
WARNING: These accounts, and their private keys, are publicly known.
Any funds sent to them on Mainnet or any other live network WILL BE LOST.
Account #0: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000 ETH)
Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
Account #1: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 (10000 ETH)
Private Key: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
....
WARNING: These accounts, and their private keys, are publicly known.
Any funds sent to them on Mainnet or any other live network WILL BE LOST.
Just remember, it is temporary, and after you stop the node, all data in the node will be lost.
For now, you need to run the deploy script :
npx hardhat run scripts/deploySimpleStorage.ts
As result of this program you can see address of your deployed contract
SimpleStorage deployed to 0x5FbDB2315678afecb367f032d93F642f64180aa3
The combination of Hardhat and Node.js offers a powerful environment for developing, testing, and deploying smart contracts in the Web3 ecosystem. As you delve deeper, you'll find an expansive community and myriad plugins and tools to enhance your development process.
Boooring… I have seen this guide many times, some readers may say, and I apologize for wasting their time and promise to make a continuation of the article with the prize draw contract and the NFT contract (I know this will be a very timely post)
As we know from the history of development in Web 2.0, any library becomes outdated approximately yesterday, so everything described in this article may become outdated approximately tomorrow, so I strongly recommend studying the official documentation
Links:
https://hardhat.org/hardhat-runner/docs/getting-started
https://docs.opensea.io/docs/1-structuring-your-smart-contract (really useful resource)