Generating wallet accounts with readable hex values
Prefer Twitter? Read this post as a Twitter thread here:

Did you know you can generate wallets with readable hex values? This one for example, starts with "2bad":
0x2BadC4395130B7D232C20eea773F831260e974F2
In this article we’ll learn how. Before I start, however, I want to make very clear that this should only be done with test accounts.
First, let's understand where wallet accounts come from.
An Ethereum wallet address is the last 20 bytes of a hashed public key that was derived from a *private* key, using some fancy cryptographic algorithm called ECC (elliptic-curve).
What is that private key and how do you get one?
A private key is really just a large number, ideally created using a source of high entropy (randomness). Entropy is important because we don't want anyone to guess that number.
Needless to say: Don't share it with anyone. ☝🏼
Simply speaking, you could create a private key by rolling a dice a bunch of times and note down the numbers, if you're confident this is random enough. 🎲
Otherwise, hard and software wallets take care of that for you. From a private key, we derive the public key using the aforementioned algorithm. For us, it's not important to understand how that algorithm works, but for a deep dive on elliptic curves, check out this video:
Okay, what is a public key? You can think of the public key as yet another big number, with the big difference that you can always calculate that number using your private key (but not the other way around). We use public keys as digital 🆔s.
The public key is then "hashed" using an algorithm called keccak256. A hash function creates a fixed-sized digital fingerprint of any given input. The same input always creates the same output. Here's the fingerprint for "hello-world" (using sha256):
The last 20 bytes of that fingerprint makes our Ethereum wallet address. If "hello-world" was our public key, here's what our wallet address would look like:
0x4497311b6fe1e2cdbe497dfb968da2bcf0dc2ab4
Okay, how do we create addresses that start with a certain sequence of bytes?
The harsh reality is, that we'd have to keep generating private keys and pass them through the process described in this thread, until we find an address that matches our target byte sequence.
Sounds a lot like mining, doesn't it? ⛏️
Luckily, there's a tool we can use to do the work for us!
Foundry, a toolbox for developers, provides a lot of utilities, including a tool to generate private keys from which we can derive addresses that start or end with a given byte sequence.
Here's how to install it:
curl -L https://foundry.paradigm.xyz | bash
Once installed, we have a bunch of new commands available in our environment, one of them being `cast`.
cast provides subcommands to perform things like RPC calls to your Ethereum node, as well as wallet utilities and more.
Here's how we can generate a wallet that starts with "2bad" as shown at the beginning of this thread, using the `cast wallet vanity` subcommand.
🚫 DO NOT USE THIS PRIVATE KEY FOR REAL FUNDS 🚫
Here's another one, starting with "dice". Again, DO NOT use any of the private keys shown in this article.
Prefer an address that *ends* with your target byte sequence instead? cast got you covered. Simply use the --ends-with
option:
You want to keep your target byte sequence short. The longer the sequence, the harder it is for cast to find an address for you and the longer it will take.
Remember, there are way more addresses that do *not* start or end with your target byte sequence than ones that do. 💡
This also brings me to why you should ⚠️ only do this for test accounts. ⚠️
By enforcing a "readable" byte sequence at the start or end of your wallet address, you're essentially removing entropy, which in theory makes it easier for hackers to brute force your private key.
Only use vanity accounts for fun or testing. Here are a few more hex values for you to play around with:
b0ca ➡️ boca
c0d3 ➡️ code
b055 ➡️ boss
1dea ➡️ idea
5eed ➡️ seed
Hope you've learned something new today, anon. ✌🏼🐰