Deploy an Efficient-Address Contract: A Walkthrough

Because gas can get expensive!

You might have heard that gas-efficient Ethereum contract addresses are supposedly a thing. Maybe you’d even like to use one for your next contract, assuming it’s not too much extra hassle. Most likely, you have no idea what the hell I’m talking about. If you fall into the latter category, I encourage you to check out the last post for all the gruesome details — though afterward you still might have no idea what the hell I’m talking about. Here’s the gist of it: addresses with extra zero bytes often cost less gas to use, and there’s a more effective way to create contracts that reside at those addresses.

Rather than re-hash all the reasons why you might want to use a contract with a gas-efficient address, let’s get right to work and learn how to deploy your next contract with one. Depending on your particular use-case, your compute capabilities, your technical acumen, and your relationship status, you have six options:

  1. Deploy the contract the usual way to a non-efficient address. (yawn…)
  2. Deploy the contract to an efficient address the old-school way via CREATE.
  3. Deploy the contract to an efficient address using CREATE2 and a factory contract (such as the cleverly-named Create2Factory).
  4. Deploy an upgradeable transparent proxy to an efficient address and set your contract up as the implementation using Pr000xy.
  5. Get some Pr000xy tokens from a friend and use them to claim an upgradeable transparent proxy, skipping the trickier bits of the process.
  6. Remember that it’s your anniversary, drop everything you’re doing, and start writing a sonnet and baking cupcakes.

You’re on your own when it comes to options 1 and 6, so we’ll focus our attention on options 2 through 5. If you’re not already comfortable with deploying and/or interacting directly with smart contracts, you’re probably not the the target audience for much of what will follow. Let’s dive in.

The OG Method

Vanity addresses have been a thing for about as long as addresses have been a thing. They’re more “memorable” or more “lucky”, both desirable traits in a cryptocurrency space awash with hype-fueled charlatans and degenerate gamblers. The Ethereum Name Service set out to solve the “memorable” bit, but that still left the “lucky” part in need of a solution. For that reason, vaniteth was created (well, the actual reason was to help make the ENS registry address itself memorable, but I digress). In short, here’s the method:

  • Generate a private key using some reliable source of entropy and derive the associated address.
  • Determine the contract deployment address after first executing up to N transactions, where N is the highest nonce you’re willing to use.
  • Repeat until you’ve found an address that meets your specifications.
  • Fund the address and make enough dummy transactions to get the nonce to the appropriate spot.
  • Finally, deploy the contract and bask in the technical feat you’ve pulled off.

This method gets the job done, and does so more quickly when using large values for N, but has a few big drawbacks:

  • You have to be extra careful to get the nonce just right when deploying the contract, and end up wasting time and gas as you have to then fund the address and make a bunch of transactions to increment the nonce.
  • You have to generate lots of private keys, which reduces the speed at which you can iterate through candidates and requires a good source of entropy unless you want to get hacked.
  • Even if you have good entropy, you can still get hacked if someone’s got a keylogger on your machine or a backdoor in the mining software or can swipe the private key via some other means, at which point they can steal your coins and/or push the nonce too high for you to actually deploy the contract to the correct address! (I should also mention that split-key address derivation can be used as a defense against this—however, remember that contracts don’t have private keys, so you still have to fund the address, increase the nonce, and deploy the contract.)

So, if you’ve got patience, nostalgia, great op-sec, and a hole in your pocket, then this one’s got your name all over it! The good news is that there are already highly-performant libraries for this option — check out profanity or ethaddrgen to get after it.

The New Kid On The Block

With the advent of Constantinople (live now on Ropsten and scheduled for block 7,280,000 on mainnet), there’s a new way to deploy contracts: CREATE2. Rather than using the caller’s address and a nonce as inputs when determining the contract deployment address, it uses the calling contract’s address, a 32-byte salt, and the initialization code of the contract being deployed. This has a few advantages over the old status quo as it pertains to vanity addresses:

  • There’s no need to generate new keypairs, or even a requirement for secure entropy, as the salt can just be incremented (as long as some care is taken to avoid collisions so you’re not repeatedly checking against the same salt). This increases the speed at which you can iterate through candidates and defends against getting hacked as a result of a deficit in knowledge of advanced cryptography and secure random number generation.
  • You don’t need to fund a new, potentially pwned address and muck about with the nonce, burning through your ether and your sanity: just send one transaction from an account you already control and be done with it.
  • The attack surface goes way down, with your trusty private key safe and sound on your hardware wallet — you can even kick it off from another, already-existing contract if you like. (You do use a hardware wallet, right?)

This is all well and good, but comes with an important caveat (there’s always caveats, damnit!) to bear in mind. Rather than just leaving out the to field in a transaction and slapping the initialization code on as call data, you’ll need to go through a factory contract that will call CREATE2 for you. That factory contract better have some access controls on what salts it will accept and from whom, or else you’ll be vulnerable to front-running: someone who’s watching the transaction pool can see when you submit a salt and beat you to the punch. A good way to combat this issue is for the factory contract to use msg.sender as the first 20 bytes of the salt, leaving the last 12 available for finding the desired contract address (which still leaves 2⁹⁶ or about 79 thousand trillion trillion possibilities per caller).

Let’s walk through the steps to deploy a basic contract using Create2Factory:

  • Get the initialization code for the contract you want to deploy and compute its 32-byte keccak-256 hash.
  • Determine the address that Create2Factory will deploy the contract to when given the initialization code hash and a salt, and repeat with new salts until you’ve found an address that meets your specifications.
  • Deploy the contract by calling into Create2Factory and providing the salt and contract initialization code as arguments, remembering to call it from the address encoded in the start of the salt.

Pretty easy by comparison, eh? Here’s a way to find a salt that we can give to Create2Factory on Ropsten that will result in a contract with an efficient address. It uses the humble create2crunch address miner along with the venerable Truffle & Web3.js v1.0 libraries (install Rust v1.31.1, Node v.11.4.0, and Yarn first if you don’t have them already):

### Set up new project from scratch and install stuff.  [¬°-°]¬ ###
$ yarn global add truffle # install truffle if you need to
$ mkdir myFirstEfficientAddress && cd myFirstEfficientAddress
$ truffle init
$ yarn init # fill in the fields (or don't, I'm not your mother)
$ yarn add web3@1.0.0-beta.37
### Behold: the example contract source code!  ⊹╰(⌣ʟ⌣)╯⊹ ###
$ cat >./contracts/ExampleContract.sol <<EOL
pragma solidity ^0.5.0;
contract ExampleContract {
function exampleFunction() public pure returns (bool) {
return true;
### Compile time!  ᕕ(⌐■_■)ᕗ ♪♬  ###
$ truffle compile
### Create a little script for hashing init code.  ._.)/\(._. ###
$ cat >./getInitCodeHash.js <<EOL
var Web3 = require('web3')
const artifact = require('./build/contracts/ExampleContract.json')
const initCodeHash = Web3.utils.keccak256(artifact.bytecode)
### Let's get the init code itself while we're at it.  ƪ(ړײ)‎ƪ ###
$ cat >./getInitCode.js <<EOL
const artifact = require('./build/contracts/ExampleContract.json')
### Assign all the various arguments.  ᕕ( ᐛ )ᕗ ###
$ export FACTORY="0xa779284f095ef2eBb8ee26cd8384e49C57b26996"
$ export INIT_CODE=`node getInitCode.js`
$ export INIT_CODE_HASH=`node getInitCodeHash.js`
### Install create2crunch and get crunching!  ༼つಠ益ಠ༽つ ─=≡ΣO)) ###
$ git clone
$ cd create2crunch
$ cargo run --release $FACTORY $CALLER $INIT_CODE_HASH # then ^c
### Once you find one, go grab it. Hurray!  (๑•̀ㅂ•́)ง✧ ###
$ export SALT=`head -1 efficient_addresses.txt | cut -c1-66`
### You'll need these for the deployment step.  (っˆڡˆς) ###
$ echo salt: $SALT
$ echo init code: $INIT_CODE
$ echo init code hash: $INIT_CODE_HASH

As an aside, there’s also an experimental GPU option included as part of create2crunch if you’re feeling extra ambitious. Give it a try!

With our salt in hand, it’s time to make the magic happen. There are a lot of ways to do this, but we’ll keep it simple: head over to the contracts section of MyEtherWallet (Ropsten version) and drop in the Create2Factory contract address:


as well as the contract ABI:


From here, you’ll probably want to verify that you’ve got the right address by calling the findCreate2Address view function, passing in the salt and the init code hash. Make sure that the first 20 bytes of the salt match your address. Once you’re satisfied, deploy the contract at the efficient address using callCreate2, passing in the salt and the contract initialization code, and making sure you set the gas limit plenty high (it’s Ropsten — go all-out, big spender). That’s it! Bonus points for calling exampleFunction on the new contract and getting back that sweet, sweet truthy bool.

Team Players Unite!

The Create2Factory method is great, as long as you have a particular, unique contract you want to deploy and are willing to do all the legwork required to find an efficient address for it yourself. But, as my grandfather likes to say, “many hands make light work.” (If he could wrap his head around crypto beyond “what’s the deal with ‘the Bitcoin’ I keep hearing about on the news,” I’m sure he’d appreciate the analogy.) If a group of efficient-address seekers all settle on a shared factory contract, block of initialization code, and relative value for each efficient address, they can tap into a whole bunch of the goodies we discussed in the last post, chief among them the ability to capitalize on all the efficient contract addresses found along the way as they endeavor to reach efficient-address nirvana.

Pr000xy establishes a common baseline for that initialization code by using upgradeable transparent proxies (the ones used in ZeppelinOS — you should play around with zos if you haven’t yet, pretty neat-o bit of tooling there). Everyone deploys the same version, and then they set it up however they like once it’s already been deployed by pointing it at an implementation contract with all the desired logic. It also gives each contract address a value in Pr000xy tokens, which bestows some welcome fungibility. Plus, you now have a contract that you can upgrade! (Of course, you can always relinquish that ability if you have a “Code is Law!” sticker on your laptop shell.)

Note that there are some extra wrinkles to consider when working with upgradeable transparent proxies. To name a few: you can only call admin methods (changing the admin or the implementation) from the admin account, you cannot call into the logic contract from the admin account, you have to replace constructors with initialization functions and remember to call them, you have to take care not to inadvertently reuse storage slots when upgrading, and your proxy’s toast if the logic contract hits a selfdestruct.

To elaborate on that last point, there’s a sneaky edge case to be aware of when dealing with contracts deployed via CREATE2 (see this discussion for more context): if a contract is selfdestructed, it can then be redeployed! This means that, should someone end up destroying a contract that you originally created via Pr000xy, you can deploy it again and receive the same reward twice. Also, be very careful interacting with any CREATE2-derived contracts that have selfdestruct opcodes or can delegatecall out to other contracts that might cause them to selfdestruct. Obviously, upgradeable proxies fall into this latter category, so consider setting up adequate governance and other controls on the contract’s upgrade administrator.

With that in mind, let’s proceed to an example, working from the Pr000xy Github repo and using the provided address miner (create2crunch has much better performance, but we’re in “testing-mode” here and you already know how to use it):

### Pr000xy supplies the init code, so just supply the caller. ###
### Pull down the repo, install dependencies, & build contracts. ###
$ git clone
$ cd Pr000xy
$ yarn install
$ yarn build
### Mine until you're satisfied & get salt - it's all you need. ###
$ yarn mine $CALLER ## then ^c
$ export SALT=`head -1 valuableProxies.txt | cut -c1-66`
$ echo salt: $SALT

Then, we do the same drill as before: in the contracts section of MyEtherWallet (Ropsten version), provide the Pr000xy contract address:


as well as the contract ABI (I know, there’s a lot going on here — we can get into it some other time):


Then, check the salt using findProxyCreationAddress. From here, you can use your salt to mint some Pr000xy tokens via createProxy, or you can set up the transparent proxy for yourself right away with createAndClaim. I’d allocate around 700,000 gas for the former, and in the latter case, I’d tack on a bunch more to account for whatever beastly logic you end up stuffing into your initialize function on the logic contract. (Just kidding, I know you write concise, modular contracts.) From here, the digital world is your oyster!

What’s Mine Is Yours

In case you’d rather skip the whole address-mining ordeal, you can always pick up some Pr000xy tokens and burn them in order to claim a transparent proxy that’s already been created.

First, let me be crystal-clear: if and when Pr000xy goes live on mainnet, DO NOT PURCHASE Pr000xy TOKENS FROM ANYONE UNLESS YOU ACTUALLY NEED AN UPGRADEABLE TRANSPARENT PROXY WITH AN EFFICIENT ADDRESS AND INTEND TO CLAIM IT SOON! Better yet, I recommend against purchasing them at all — they are a highly experimental, HIGHLY DEFLATIONARY token with NO ORGANIZATION BACKING THEM and NO RIGHTS, DIVIDENDS, OR EXPECTATION OF ANY FORM OF PROFIT. (IANAL, but would very much like to avert any drama should one of the multitude of regulatory bodies claiming authority over cryptocurrencies take an interest in this little experiment, so please excuse the corporate-speak.)

That being said, here’s how it’s done (on Ropsten for now):

  • Get some test tokens. (Get in touch if you’d like me to send you some — you can find me on the internet.)
  • Fill in the contracts section of MyEtherWallet (Ropsten version) with Pr000xy’s address 0x000000009a9fc3ac5280bA0D3eA852E57DD2ac1b as well as the contract ABI (it’s the big, ugly block of code you had to scroll through to get here).
  • Figure out how “rare” a proxy you can afford via getValue to check particular values for various combinations of leading zero bytes and total zero bytes, or getReward to see how arbitrary addresses are valued. (Remember that a zero byte actually “looks like” a pair of zeroes.)
  • Find an available proxy by first calling countProxiesAt to check if a proxy with your desired number of leading and total zero bytes is available.
  • If one is available, claim the latest available proxy by calling claimLatestProxy with the same arguments for leading and total zero bytes. You can deploy a logic contract and set the whole thing up right when you claim it, or you can leave the owner and implementation arguments to the null address and the data argument empty to just assign ownership to the address you’re claiming it with and deal with setting it all up after the fact.

So there you have it — you know the drill for deploying contracts with addresses that have shed a few pounds. If you want to get involved, start playing around with Create2Factory and Pr000xy (and don’t be shy about asking questions in the telegram channel). Now, go forth and exert a touch of effort now to make your contracts a little more efficient in the future!