Generating a vanity address is a simple process of trial-and-error, and the same process can be used to search for accounts having some other property.
Contract addresses are determined by the account of the creating account and its nonce - specifically, they're the hash of the RLP encoding of those two values. Thus, you can search for an account that generates a vanity contract address like this:
- Generate a random private key
- Derive its public key and address
- Derive the address of the first contract it would create from its address and a nonce of zero
- Repeat from 1
Here's some simple code that uses pyethereum to do this:
import os
from ethereum.keys import privtoaddr
from ethereum.utils import mk_contract_address
import zlib
smallest = None
keys = {}
while True:
privkey = os.urandom(32)
addr = privtoaddr(privkey)
contractaddr = mk_contract_address(addr, 0).encode('hex')
compressedsize = len(zlib.compress(contractaddr, 9))
if compressedsize <= 42:
print "0x%s: %d" % (contractaddr, compressedsize)
keys[contractaddr] = privkey.encode('hex')
if smallest is None or long(contractaddr, 16) < long(smallest, 16):
smallest = contractaddr
print "0x%s" % smallest
keys[contractaddr] = privkey.encode('hex')
In this case, it looks for addresses with the most leading zeroes, and the keys that compress the smallest - using zlib as a crude estimator of Kolmogorov Complexity, since addresses with many repetitions will compress smaller.
You can replace the fitness function with anything you would like, of course - to generate the address eventually used for the ENS registry, I used a function that rated addresses based on how many strictly incrementing digits they started with.