Impersonating Accounts With Hardhat

Samson Adesanoye
Coinmonks
Published in
4 min readFeb 3, 2023

--

During the development or review of smart contracts, it may be necessary to evaluate your smart contracts against pre-existing smart contracts such as decentralized exchanges or flash loans without the cost of spending real ether. In this article, you will learn how to fork the mainnet and impersonate an account using Hardhat.

Photo by Fares Hamouche on Unsplash

What is Hardhat?
Hardhat is an Ethereum development environment for professionals, it comes with tools such as Hardhat runner, network, and VSCode extension that make development flexible, extensible, and fast.

Why Impersonate Account?
- It allows manipulating the signer even if you don’t have access to its private key.
- It allows testing a contract with access controls, address is all needed to impersonate it.
- It allows testing mainnet smart contracts without using real ethers.

Prerequisite:

  1. Install node and npm

Create New Hardhat Project

We will be using a hardhat project, you can feel free to skip this if you already have.

  1. Create folder project: Open your terminal and enter the command below.
mkdir mainnet-fork-tutorial
cd mainnet-fork-tutorial

2. Initiate npm in the project: Initialize npm in the created project.

npm init -y

3. Install hardhat

npm install --save-dev hardhat

4. In the same directory where you installed Hardhat run:

npx hardhat

Select create a JavaScript project with your keyboard and hit enter, to create a fresh hardhat project; this might take time depending on your internet connection.

5. Install dotenv: we will be using dotenv to store environment variables.

npm i dotenv

Create API Key

We need an remote procedure call (RPC) node, Hardhat recommends we make use Alchemy because they offer Full archive nodes; which are a type of node that contains all the information about a blockchain from the genesis or original block.

  1. Create an alchemy account: Create your free alchemy account at https://auth.alchemy.com/signup and confirm your email.
https://auth.alchemy.com/signup

2. Create an app: In your alchemy dashboard, click on + CREATE APP button. This brings a popup to create a new app. Fill in the name and description in the form and click CREATE APP button. Example:
Name: mainnet-fork
Description: Description of what your app does so you can keep track.
Chain: Ethereum (default selection)
Network: Mainnet (default selection)

3. View key: Once your new app is created, the pop disappears. The app appeared under the Personal Apps table. Locate the newly created app in the table and click on the view key button. Copy the API KEY.

COPY HTTPS

Fork Ethereum mainnet

Open the newly created mainnet-fork-tutorial project with your favorite editor.

  1. Create .env file: create a .env file in the root of mainnet-fork-tutorial project.
MAINNET_RPC_URL=your_app_api_url_from_alchemy

2. Edit hardhat.config.js: Edit hardhat.config.js we will be adding a new network called hardhat in module.exports object.

require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
solidity: "0.8.17",
networks: {
hardhat: {
forking: {
url: process.env.MAINNET_RPC_URL,
},
chainId: 1,
},
},
};

You can also pin the block number:

networks: {
hardhat: {
forking: {
url: process.env.MAINNET_RPC_URL,
blockNumber: 14390000
}
}
}

3. Run Network: In your terminal, enter the command below to start hardhat node.

npx hardhat node
Congratulations you just forked mainnet

Impersonating accounts:

Hardhat Network enables you to assume the identity of any address, enabling you to initiate transactions from that account without requiring access to its private key. We will impersonate vitalik’s address and send ethers on his behalf.

  1. Create a transaction.js file in the root of your project.
  2. In your transaction.js, add the code below.
const { ethers, network } = require("hardhat");

async function send() {
const vitalik_address = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B";
const addressTo = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266";

// impersonating vitalik's account
await network.provider.request({
method: "hardhat_impersonateAccount",
params: [vitalik_address],
});

// make vitalik the signer
const signer = await ethers.getSigner(vitalik_address);

console.log(
"Vitalik account before transaction",
ethers.utils.formatEther(await signer.getBalance())
);

// create transaction
const tx = {
to: addressTo,
value: ethers.utils.parseEther("0.01"),
};

const recieptTx = await signer.sendTransaction(tx);

await recieptTx.wait();

console.log(`Transaction successful with hash: ${recieptTx.hash}`);
console.log(
"Vitalik account after transaction",
ethers.utils.formatEther(await signer.getBalance())
);
}

send()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

3. Run transaction.js in the terminal

node transaction.js
node transaction.js

Note: After the complete transaction, the balances of the account involved are reset back to their default.

Conclusion
Impersonating an account can go beyond sending ether to another account, one can interact with smart contracts, dAPPs, etc.

Resources:

Fork Ethereum Mainnet Locally with Hardhat | Call Contract Methods on Wrapped Ether and CurveFi

Forking other networks | Ethereum development environment for professionals by Nomic Foundation

How to Fork Ethereum Mainnet

w to trading? Try crypto trading bots or copy trading on best crypto exchanges

--

--