Interact With Hardhat

Familiarity with Linux/Javascript is essential.


Hardhat is a powerful Ethereum development environment designed to assist developers in managing and automating the repetitive tasks associated with building smart contracts and decentralized applications (DApps). Notably, Hardhat has the capability to directly interact with Darwinia's Ethereum API, enabling developers to deploy their smart contracts onto the Darwinia network. This compatibility allows developers to leverage Hardhat's features and tools when working with Darwinia, streamlining the development process and facilitating the creation of robust and reliable applications.

Setting up a project

In this tutorial, we will explore the usage of hardhat by deploying a contract and performing various contract functionalities. The tutorial involves multiple script files, so let's create a new JavaScript project calledĀ example-with-hardhatĀ to organize and manage the code effectively. This project will serve as a workaround for implementing the hardhat functionality.
mkdir example-with-hardhat && cd example-with-hardhat && npm init --y
Install the hardhat by runing the following command:
npm install --save-dev hardhat
If you runĀ npx hardhatĀ now, you will be shown some options to facilitate project creation:
$ npx hardhat 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.3 ? What do you want to do? ā€¦ ā–ø Create a JavaScript project Create a TypeScript project Create an empty hardhat.config.js Quit
SelectĀ Create a JavaScript project, a simple project creation wizard will ask you some questions. After that, the wizard will create some directories and files and install the necessary dependencies. The most important of these dependencies is theĀ Hardhat Toolbox, a plugin that bundles all the things you need to start working with Hardhat.
The initialized project has the following structure:
contracts/ scripts/ test/ hardhat.config.js
These are the default paths for a Hardhat project.
  • contracts/Ā is where the source files for your contracts should be.
  • test/Ā is where your tests should go.
  • scripts/Ā is where simple automation scripts go.

Contract Interaction

The network provider used in this tutorial is the Pangolin Testnet. However, the concepts and techniques covered in this tutorial are applicable to other Darwinia networks as well.

Prepare And Compile Contract

Create a smart contract file under the contracts by running this command:
touch storage.sol
To showcase the interaction with the smart contract, we have prepared a simple Solidity smart contract. You can find the contract code pasted into theĀ storage.solĀ file. This contract will serve as the basis for demonstrating how to interact with it using hardhat.
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.2 <0.9.0; contract Storage { uint256 number; /** * @dev Store value in variable * @param num value to store */ function store(uint256 num) public { number = num; } /** * @dev Return value * @return value of 'number' */ function retrieve() public view returns (uint256){ return number; } }
This contract is straightforward and easy to understand. It consists of two functionalities: storing a number and retrieving the updated number. Let's proceed to learn how to interact with this contract using hardhat.
To compile your contracts in your Hardhat project, use the built-inĀ compileĀ task:
npx hardhat compile
The output looks like this and the compiled artifacts will be saved in theĀ artifacts/Ā directory by default.
Compiled 1 Solidity file successfully

Update Hardhat Config

Before working with the contracts, there are a few basic configurations that need to be set up. Replace the defaultĀ hardhat.configĀ file with the following content. This configuration includes the Pangolin network RPC information and adds a test account:
require("@nomicfoundation/hardhat-toolbox"); /** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: "0.8.19", defaultNetwork: "pangolin", networks: { pangolin: { url: "https://pangolin-rpc.darwinia.network", accounts: ["0xd5cef12c5641455ad949c3ce8f9056478eeda53dcbade335b06467e8d6b2accc"] } } };
By updating theĀ hardhat.configĀ file with this content, you will have the necessary configurations in place to interact with the Pangolin network and use the test account for testing purposes.

Deploy Storage Contract

And paste the following content into it the deploy.js under scripts:
const hre = require("hardhat"); async function main() { const storage = await hre.ethers.deployContract("Storage"); await storage.waitForDeployment(); console.log(`Contract deployed at address: ${storage.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; });
Start the deployment by running the command:
npx hardhat run --network pangolin scripts/deploy.js
The output like this:
Contract deployed at address: 0x46c66F6c65C7550a1CF94754979a1A52dB6C26c9
0x46c66F6c65C7550a1CF94754979a1A52dB6C26c9 is the address of the deployed storage contract, as a unique identifier for that contract. It will be used later to store and retrieve the number.

Using Hardhat Console

Hardhat comes built-in with an interactive JavaScript console. You can use it by runningĀ npx hardhat console:
$ npx hardhat console Welcome to Node.js v12.10.0. Type ".help" for more information. >
Using the console tool, interacting with the deployed contract becomes incredibly convenient. Let's instantiate a storage contract and bind its address to it. By doing so, we will be able to easily interact with the contract and perform various operations on it.
# In the harhat console const Storage = await ethers.getContractFactory('Storage'); const storage = await Storage.attach('0x46c66F6c65C7550a1CF94754979a1A52dB6C26c9');

Store Number

# In the harhat console await storage.store(3);
The output:
ContractTransactionResponse { provider: HardhatEthersProvider { _hardhatProvider: LazyInitializationProviderAdapter { _providerFactory: [AsyncFunction (anonymous)], _emitter: [EventEmitter], _initializingPromise: [Promise], provider: [BackwardsCompatibilityProviderAdapter] }, _networkName: 'pangolin', _blockListeners: [], _transactionHashListeners: Map(0) {}, _eventListeners: [] }, blockNumber: null, blockHash: null, index: undefined, hash: '0xbc28842eaa299ac5f4ebbd781a34dd0ae957009f8f9764942ca574fae7c76d47', type: 2, to: '0x46c66F6c65C7550a1CF94754979a1A52dB6C26c9', from: '0x6Bc9543094D17f52CF6b419FB692797E48d275d0', nonce: 11, gasLimit: 45100n, gasPrice: 182721978177n, maxPriorityFeePerGas: 0n, maxFeePerGas: 182721978177n, data: '0x6057361d0000000000000000000000000000000000000000000000000000000000000003', value: 0n, chainId: 43n, signature: Signature { r: "0x191e493eed26c34426522a9e29d913dd0c5a94ae62b44e398b8e0eb72d597b90", s: "0x474e5f1b1f363047b9a7c8c99bdd9f9429946a12acb876c8741ac5ce04a77438", yParity: 0, networkV: null }, accessList: [] }

Retrieve Number

# In the harhat console await storage.retrieve();
The output: