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.