Developer guide
EOA Vanity Address vs CREATE2 Vanity Contract Address
How a vanity wallet (EOA keypair search) differs from a vanity contract address mined with a CREATE2 salt, with the EIP-1014 formulas.

Two kinds of accounts, two kinds of search
Ethereum has externally owned accounts (EOAs), controlled by a private key, and contract accounts, controlled by code. Both use the same 20-byte address format, but their addresses are computed differently, so a vanity search for each one varies a different input. For an EOA the input is a 256-bit private key; for a contract it is either the deployer's nonce (CREATE) or a 32-byte salt (CREATE2).
The expected number of attempts is the same in both cases, 16^n for an n-character case-insensitive pattern, because both addresses come from Keccak-256 output. What differs is the cost of each attempt, the secrecy of the result and who can reproduce it.
EOA vanity search: a keypair search
An EOA address is the last 20 bytes of keccak256 over the 64-byte public key, and the public key is the private key multiplied by the secp256k1 generator point. A vanity generator repeats that derivation for a huge number of candidate keys. Efficient generators avoid a full scalar multiplication per attempt by adding the generator point to the previous public key, which corresponds to incrementing the private key by one.
The output is a private key, so the whole security of the account depends on how the starting point was chosen. If the starting key comes from too little entropy, an attacker can redo the search, which is exactly what happened with the Profanity vulnerability. A safe EOA generator must seed from a cryptographically secure source with the full 256 bits of entropy, and should run offline on hardware you control.
The incremental method also shapes how parallel workers must be seeded. Each GPU thread or machine needs its own securely random starting key; if workers share a predictable base and differ only by a small counter, the total key space actually searched is tiny, which recreates the weakness of a low-entropy seed. Expected attempts are unchanged by this design, at 16^n for n hex characters, so a 7-character EOA prefix still averages 268,435,456 keys.
CREATE: the address depends on the deployer's nonce
The original CREATE opcode, also used when a transaction has no to field, derives the new address from the sender and its nonce: address = keccak256(rlp([sender, nonce]))[12:]. The nonce of an EOA is its transaction count; the nonce of a contract counts the contracts it has created and starts at 1 per EIP-161.
Because the only free variable is the nonce, CREATE offers a crude vanity option: grind for a deployer key whose nonce-0 contract address matches the pattern, then make the deployment the very first transaction from that key. For example, Hardhat's public test account 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 always deploys its first contract to 0x5FbDB2315678afecb367f032d93F642f64180aa3. Any accidental transaction before the deployment burns the nonce and loses the address.
Worked CREATE example: the RLP encoding
RLP encodes the list [sender, nonce] compactly. The 20-byte sender is prefixed with 0x94 (0x80 plus its length of 20), a nonce of 0 is the empty string 0x80, and nonces from 1 to 127 are a single byte equal to the nonce. The whole list has a payload of 22 bytes, so it is prefixed with 0xd6 (0xc0 plus 22). Larger nonces take more bytes and change these prefixes.
For the publicly known test address of private key 1, 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf, the nonce-0 encoding is d6 94 7e5f...395bdf 80 and its first contract lands at 0xF2E246BB76DF876Cef8b38ae84130F4F55De395b. At nonce 1 the final byte becomes 01 and the address becomes 0x2946259E0334f33A064106302415aD3391BeD384. Every nonce gives an unrelated address, which is why CREATE vanity searches must grind the deployer key itself.
rlp([sender, 0]) = d6 94 <20-byte sender> 80
rlp([sender, 1]) = d6 94 <20-byte sender> 01
address = keccak256(rlp)[12:]
# ethers v6
import { getCreateAddress } from "ethers";
getCreateAddress({ from: "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf", nonce: 0 });
// 0xF2E246BB76DF876Cef8b38ae84130F4F55De395bCREATE2: the address depends on a salt and the code
EIP-1014, activated in the Constantinople upgrade in 2019, added CREATE2 with a formula that does not depend on the nonce: keccak256(0xff ++ deployer ++ salt ++ keccak256(init_code))[12:]. Here 0xff is a single constant byte, deployer is the 20-byte address of the contract executing CREATE2, salt is any 32-byte value and init_code is the full creation bytecode including constructor arguments.
To mine a vanity contract address, you fix the deployer and the init code hash and iterate the salt. Each attempt is one Keccak-256 over 85 bytes, with no elliptic-curve work, so a salt search is far cheaper per attempt than a keypair search. The salt can be published freely; anyone can recompute the address, which is the point of a deterministic deployment.
Factories often wrap the raw opcode. Solidity exposes CREATE2 through the syntax new Contract{salt: s}(args), which uses the current contract as the deployer, and many projects deploy through a shared factory so the deployer address is identical on every network. Whatever wrapper you use, the address you mine against must be the address of the contract that executes the opcode at deployment time.
The 0xff prefix exists to keep CREATE2 addresses from colliding with CREATE addresses. EIP-1014's rationale notes that 0xff could only be the first byte of an RLP encoding for data many petabytes long, so a CREATE2 preimage can never equal a real CREATE input. EIP-1014 also charges extra gas for hashing the init code, 6 gas per 32-byte word, because CREATE2 must compute keccak256(init_code) on-chain.
// ethers v6: compute a CREATE2 address
import { getCreate2Address, keccak256, ZeroHash } from "ethers";
const deployer = "0x4e59b44847b379578588920cA78FbF26c0B4956C"; // deterministic deployment proxy
const salt = ZeroHash; // 32 bytes
const initCodeHash = keccak256("0x00");
getCreate2Address(deployer, salt, initCodeHash);
// 0x24C4fD2Db1Cf4Cb1aEc651CC0E060A00D400e784
// EIP-1014 example 0: deployer 0x00..00, salt 0x00..00, init_code 0x00
// -> 0x4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38EOA keypair search vs CREATE2 salt search
The practical differences decide which tool you need.
| Property | EOA vanity (keypair) | CREATE2 vanity (salt) |
|---|---|---|
| Varied input | 256-bit private key | 32-byte salt |
| Work per attempt | Elliptic-curve step plus Keccak-256 | One Keccak-256 |
| Result | Secret private key | Public salt |
| Who can redo it | Nobody, if entropy is sound | Anyone with deployer and init code |
| Fixed inputs | None | Deployer address and exact init code |
| Typical tools | Offline keypair generators | create2crunch, Uniswap HookMiner, CreateX salts |
| Main risk | Weak randomness leaks the key | Front-running or init code mismatch |
Pitfalls when mining a CREATE2 salt
A CREATE2 address is only reproducible if every input is byte-for-byte identical, so most failures come from changing something after mining.
- Changing compiler version, optimizer settings, metadata hash or constructor arguments changes keccak256(init_code) and therefore the address.
- The deployer is the contract that executes CREATE2, not your wallet. Mining against your EOA address while deploying through a factory gives a different result.
- A public salt can be front-run on a permissionless factory. Tools such as create2crunch accept a caller address, and CreateX lets the first 20 bytes of the salt equal msg.sender so only you can use it.
- Leading zero bytes have real value for gas, covered in leading-zero addresses and gas, and the same salt reproduces the address on other chains, covered in same address on every EVM chain.
Explore the related mechanism
- How Ethereum Addresses Are Derived from a Private Key — From secp256k1 private key to Keccak-256 hash, last 20 bytes and EIP-55 checksum, with an ethers v6 example and why it is one-way.
- Same Address on Every EVM Chain: EOAs, CREATE2 and CREATE3 — Why an EOA has the same address on every EVM chain, how contracts match via CREATE2 and CREATE3, and lessons from the 20M OP incident.
- Open the complete workflow guide to place these checks in order.
- Open the address generator when you have chosen a compatible format and pattern.
Frequently asked questions
Is a CREATE2 vanity address safer than a vanity wallet?
It removes one risk: no private key is created, so a weak search cannot leak a key. The contract's security then depends entirely on its code and its admin keys.
Can I mine a CREATE2 salt for a contract I deploy from my wallet directly?
No. A plain deployment transaction uses CREATE with your nonce. CREATE2 must be executed by a contract, such as a factory or the deterministic deployment proxy.
Which should I use for a vanity contract, CREATE or CREATE2?
CREATE2 in almost all cases. It needs no secret, survives accidental transactions from your wallet and reproduces across chains. CREATE vanity requires grinding a private key and keeping its first nonce unused.
Can two different contracts end up at the same CREATE2 address?
Not at the same time. The address commits to the init code hash, so different init code gives a different address for the same deployer and salt. Deployment also fails if code already exists at the target address.
Sources and editorial method
The technical references below support the concepts discussed in this article. Examples and comparison worksheets are explanatory, not measured service benchmarks.



