Impersonate any ETH address with Anvil

Andrei
3 min readApr 17, 2023

Introduction

In this article I’ll explain how you can impersonate any ETH address without needing the private key using Anvil.

If you are wondering why you would need to impersonate an ETH address is for pure testing. Let’s say we want to transfer some USDC to an ETH address within our local forked chain environment. To do that we have to get the source code of the contract then deploy it to our local chain and then mint some tokens from the contract and transfer to our desired ETH address. That would be an extra headache and it would take a longer time but happily Anvil offers a feature for impersonating accounts.

To install anvil you will need first to install foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.

Foundry consists of :

  • Forge: Ethereum testing framework (like Truffle, Hardhat and DappTools).
  • Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
  • Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
  • Chisel: Fast, utilitarian, and verbose solidity REPL.

Anvil is a local ethereum node, mostly used in mainnet fork test cases, similar to Ganache and more stable.

Download foundry

curl -L https://foundry.paradigm.xyz | bash

Set the PATH

PATH=~/.foundry/bin:$PATH

Make sure we have the foundry path set :

nano ~/.bashrc

Refresh the source

source ~/.bashrc

To install foundry run the following command :

foundryup

Then to test if anvil works just run :

anvil

If you see the following thing congratulations !

                             _   _
(_) | |
__ _ _ __ __ __ _ | |
/ _` | | '_ \ \ \ / / | | | |
| (_| | | | | | \ V / | | | |
\__,_| |_| |_| \_/ |_| |_|

0.1.0 (b7c0774 2022-05-04T16:47:13.180846+00:00)
https://github.com/foundry-rs/foundry

Available Accounts
==================
(0) 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 (10000 ETH)
(1) 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 (10000 ETH)
(2) 0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc (10000 ETH)
(3) 0x90f79bf6eb2c4f870365e785982e1f101e93b906 (10000 ETH)
(4) 0x15d34aaf54267db7d7c367839aaf71a00a2c6a65 (10000 ETH)
(5) 0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc (10000 ETH)
(6) 0x976ea74026e726554db657fa54763abd0c3a0aa9 (10000 ETH)
(7) 0x14dc79964da2c08b23698b3d3cc7ca32193d9955 (10000 ETH)
(8) 0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f (10000 ETH)
(9) 0xa0ee7a142d267c1f36714e4a8f75612f20a79720 (10000 ETH)

Private Keys
==================
(0) 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
(1) 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
(2) 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
(3) 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6
(4) 0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a
(5) 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
(6) 0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e
(7) 0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356
(8) 0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97
(9) 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6

Wallet
==================
Mnemonic: test test test test test test test test test test test junk
Derivation path: m/44'/60'/0'/0/

Base Fee
==================
1000000000

Gas Price
==================
20000000000

Gas Limit
==================
30000000

Listening on 127.0.0.1:8545

As you can see anvil like ganache provides 10 ETH addresses fullfiled with 10000 ETH each one

By default the port is set at 8545 but you can set a custom one by running anvil -p PORT

Let’s impersonate

As provider we will use the main network from Ankr. You can find there even test network RPCs.

To fork the main network through anvil you must run the following command :

anvil --fork-url https://rpc.ankr.com/eth

If you see the following thing congratulations ! You’ve forked the main network with anvil

Let’s create a python module called impersonate.py to write a function for unlocking the requested address.

Inside of our impersonate.py module copy the following code snippet:

from web3 import Web3, HTTProvider


def impersonate_account(web3: Web3, address: str):
"""
Impersonate account through Anvil without needing private key
:param address:
Account to impersonate
"""
web3.provider.make_request("anvil_impersonateAccount", [address])


if __name__ == "__main__":
PROVIDER = "https://rpc.ankr.com/eth"
web3 = Web3(HTTPProvider(PROVIDER))
impersonate_account(web3, "THE_ADDRESS")

web3.make_request("anvil_impersonateAccount", [address]) will make a request to call anvil_impersonateAccount through web3 to make the impersonated thing

Replace "THE_ADDRESS"with the address you want to impersonate.

To find a “whale” that holds a good amount of a token find the contract address then access “holders” from etherscan

Example with top holders of USDC https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#balances

To run the module just typepython3 impersonate.py in your terminal ( make sure you’ve installed web3 dependency to your virtual environment and you’ve activated the venv)

If you see anvil_impersonateAccount inside your anvil terminal congratulations you’ve impersonated the ETH account.

--

--