Using Hardhat
This page is still under development. Many functionalities of this page are still being worked on until further notice. To help our efforts, add a pull request with revised changes, thank you.

Interacting with Edgeware EVM using Hardhat

This guide walks through the process of deploying a Solidity-based smart contract to the Edgeware testnet Beresheet using Hardhat. Hardhat is a development environment to compile, deploy, test, and debug your Ethereum software. It helps developers manage and automate the recurring tasks that are inherent to the process of building smart contracts and dApps, as well as easily introducing more functionality around this workflow. This means compiling, running and testing smart contracts at the very core.
Hardhat comes built-in with Hardhat Network, a local Ethereum network designed for development. Its functionality focuses around Solidity debugging, featuring stack traces, console.log() and explicit error messages when transactions fail.
Hardhat Runner, the CLI command to interact with Hardhat, is an extensible task runner. It's designed around the concepts of tasks and plugins. Every time you're running Hardhat from the CLI you're running a task. E.g. npx hardhat compile is running the built-in compile task. Tasks can call other tasks, allowing complex workflows to be defined. Users and plugins can override existing tasks, making those workflows customizable and extendable.
A lot of Hardhat's functionality comes from plugins, and, as a developer, you're free to choose which ones you want to use. Hardhat is unopinionated in terms of what tools you end up using, but it does come with some built-in defaults. All of which can be overridden.
To follow this tutorial you should be able to:

Installation

We need to install Node.js and npm package manager. You can download directly from Node.js or in your terminal.
Mac OS
1
# You can use homebrew (https://docs.brew.sh/Installation)
2
brew install node`
3
4
# Or you can use nvm (https://github.com/nvm-sh/nvm)
5
nvm install node
Copied!
Linux
1
curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
2
3
sudo apt install -y nodejs
Copied!
You can verify that everything is installed correctly by querying the version for each package:
node -v
npm -v
As of writing of this guide, the versions used were 15.7.0 and 7.4.3, respectively.
Also, you will need the following:
  • Have MetaMask installed and connected to Beresheet
  • Have an account with funds, which you can get from the automated bot on the Edgeware discord (in construction)
    To send funds to your meta mask you have to first convert your EVM address to a mainnet address. You can do so here at the bottom of the page https://edgewa.re/keygen (Convert Metamask/EVM address to mainnet address)
Once all requirements have been met, you are ready to build with Hardhat.

Starting a Hardhat Project

To start a new project, create a directory for it:
1
mkdir EDGhat && cd EDGhat
Copied!
Then, initialize the project by running:
1
npm init -y
Copied!
You will notice a newly created package.json, which will continue to grow as you install project dependencies.
To get started with Hardhat, we will install it in our newly created project directory:
1
npm install hardhat
Copied!
Once installed, run:
1
npx hardhat
Copied!
This will create a Hardhat config file (hardhat.config.js) in our project directory.
npx is used to run executables installed locally in your project. Although Hardhat can be installed globally, we recommend installing locally in each project so that you can control the version on a project by project basis.
After running the command, choose Create an empty hardhat.config.js by using the arrow keys and enter:

The contract file

We are going to store our contract in the contracts directory. Create it:
mkdir contracts && cd contracts or by creating a new directory under our root directory 'EDGHAT' in a text-editor such as Visual Studio Code
Editing directories in the terminal can be replicated in a text-editor at any point in this tutorial.
The smart contract that we'll deploy as an example will be called Box: it will let people store a value that can be later retrieved.
We will save this file as contracts/Box.sol:
1
// contracts/Box.sol
2
pragma solidity ^0.8.1;
3
4
contract Box {
5
uint256 private value;
6
7
// Emitted when the stored value changes
8
event ValueChanged(uint256 newValue);
9
10
// Stores a new value in the contract
11
function store(uint256 newValue) public {
12
value = newValue;
13
emit ValueChanged(newValue);
14
}
15
16
// Reads the last stored value
17
function retrieve() public view returns (uint256) {
18
return value;
19
}
20
}
Copied!

Hardhat Configuration File

We need to modify our Hardhat configuration file so we can compile and deploy contracts into the Edgeware ecosystem. If you have not yet done so, connect your MetaMask Account to our ecosystem and fund it with the automated faucet bot on discord. We will use the private key of the account created to deploy the contract. If you don’t know the private key, you can export it from MetaMask.
We start by requiring the ethers plugin, which brings the [ethers.js][/integrations/ethers/] library that allows you to interact with the blockchain in a simple way. We can install the ethers plugin by running:
1
npm install @nomiclabs/hardhat-ethers ethers
Copied!
Next, we import the private key that we've retrieved from MetaMask and store it in a .json file. This file should be created under the root directory, and named private.json. Because this key is highly sensitive information, it's very important that we are not revealing any information when deploying. To ensure this, we want to create a .gitignore file under our root directory. Then, you can ignore any files by using the format: .filename or any directories by using: directory/. In our case, we are trying to ignore our private key file so it should look like this:
The private.json file must contain a privateKey entry, for example:
1
{
2
"privateKey": "YOUR-PRIVATE-KEY-HERE"
3
}
Copied!
Inside the module.exports, we need to provide the Solidity version (0.8.1 according to our contract file), and the network details. Here, we are using testnet(Beresheet) network for the following example :
If you want to deploy to a local Edgeware development node, you can use the following network details:
If you want to deploy on the Edgeware mainnet, you can use the following network details:
The Hardhat configuration file should look like this:
1
// ethers plugin required to interact with the contract
2
require('@nomiclabs/hardhat-ethers');
3
4
// private key from the pre-funded Beresheet testing account
5
const { privateKey } = require('./private.json');
6
7
module.exports = {
8
// latest Solidity version
9
solidity: "0.8.1",
10
11
networks: {
12
// Beresheet network specification
13
Beresheet: {
14
url: `https://beresheet2.edgewa.re/evm`,
15
chainId: 2022,
16
accounts: [privateKey]
17
}
18
}
19
};
Copied!
Great! We are now ready for deployment.

Compiling Solidity

Our contract, Box.sol, uses Solidity 0.8.1. Make sure the Hardhat configuration file is correctly set up with this solidity version. If so, we can compile the contract by running:
1
npx hardhat compile
Copied!
After compilation, an artifacts directory is created: it holds the bytecode and metadata of the contract, which are .json files. It’s a good idea to add this directory to your .gitignore.

Deploying the Contract

In order to deploy the Box smart contract, we will need to write a simple deployment script. First, let's create a new directory (scripts). Inside the newly created directory, add a new file deploy.js.
1
mkdir scripts && cd scripts
2
touch deploy.js
Copied!
Next, we need to write our deployment script using ethers. Because we'll be running it with Hardhat, we don't need to import any libraries.
We start by creating a local instance of the contract with the getContractFactory() method. Next, let's use the deploy() method that exists within this instance to initiate the smart contract. Lastly, we wait for its deployment by using deployed(). Once deployed, we can fetch the address of the contract inside the box instantiation.
1
// scripts/deploy.js
2
async function main() {
3
// We get the contract to deploy
4
const Box = await ethers.getContractFactory('Box');
5
console.log('Deploying Box...');
6
7
// Instantiating a new Box smart contract
8
const box = await Box.deploy();
9
10
// Waiting for the deployment to resolve
11
await box.deployed();
12
console.log('Box deployed to:', box.address);
13
}
14
15
main()
16
.then(() => process.exit(0))
17
.catch((error) => {
18
console.error(error);
19
process.exit(1);
20
});
Copied!
Using the run command, we can now deploy the Box contract to Beresheet.
1
npx hardhat run --network Beresheet scripts/deploy.js
Copied!
To deploy to an Edgeware development node, replace Beresheet for dev in the run command.
After a few seconds, the contract is deployed, and you should see the address in the terminal.
Congratulations, your contract is live! Save the address, as we will use it to interact with this contract instance in the next step.

Interacting with the Contract

Limited functionality
Let's use Hardhat to interact with our newly deployed contract in Beresheet. To do so, launch hardhat console by running:
1
npx hardhat console --network Beresheet
Copied!
To deploy to an Edgeware development node, replace Beresheet for dev in the run command.
Then, add the following lines of code one line at a time. First, we create a local instance of the Box.sol contract once again. Don't worry about the undefined output you will get after each line is executed:
1
const Box = await ethers.getContractFactory('Box');
Copied!
Next, let's connect this instance to an existing one by passing in the address we obtained when deploying the contract:
1
const box = await Box.attach('ADDRESS-GOES-HERE');
Copied!
After attaching it to the contract, we are ready to interact with it. While the console is still in session, let's call the store method and store a simple value:
1
await box.store(5)
Copied!
The transaction will be signed by your Beresheet account and broadcast to the network. The output should look similar to:
Notice your address labeled from, the address of the contract, and the data that is being passed. Now, let's retrieve the value by running:
1
(await box.retrieve()).toNumber()
Copied!
We should see 5 or the value you have stored initially.
Congratulations, you have completed the Hardhat tutorial!
For more information on Hardhat, hardhat plugins, and other exciting functionality, please visit hardhat.org.
Last modified 2mo ago