ETH Logo

EthVanity

Custom Address Generator

Buy us a coffee

Our free tools run entirely on donations. Your support pays for the servers and GPU power that make every generation possible. If we helped you today, a small donation helps keep this service free for everyone.

ETH · Ethereum network
0xcf5777b71c31146bd396cece6d3128e42d0ad9f7

Thank you for keeping us running! ❤️

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.

By Updated 7 min readRead as Markdown

Two different derivations. EOA: Public key determines the account address; CREATE2: Deployer, salt and init-code hash determine address; Control: A contract address is not an EOA private key.
Two different derivations. EOA: Public key determines the account address; CREATE2: Deployer, salt and init-code hash determine address; Control: A contract address is not an EOA private key.Open full-size diagram (SVG)Download diagram (PNG)About these visual guides
Short answer: A vanity wallet is found by generating random private keys until the derived address matches, so the result is a secret you must protect. A vanity contract address is found by searching CREATE2 salts, where address = keccak256(0xff ++ deployer ++ salt ++ keccak256(init_code))[12:], so the salt is public and nothing secret is produced.

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.

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 });
// 0xF2E246BB76DF876Cef8b38ae84130F4F55De395b

CREATE2: 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
// -> 0x4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38

EOA keypair search vs CREATE2 salt search

The practical differences decide which tool you need.

PropertyEOA vanity (keypair)CREATE2 vanity (salt)
Varied input256-bit private key32-byte salt
Work per attemptElliptic-curve step plus Keccak-256One Keccak-256
ResultSecret private keyPublic salt
Who can redo itNobody, if entropy is soundAnyone with deployer and init code
Fixed inputsNoneDeployer address and exact init code
Typical toolsOffline keypair generatorscreate2crunch, Uniswap HookMiner, CreateX salts
Main riskWeak randomness leaks the keyFront-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

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.

Read how these articles are prepared.