Create2: A Tale of Two Optcodes

Written by blockxlabs | Published 2019/03/13
Tech Story Tags: ethereum | create2 | blockchain | blockchain-technology | optcode

TLDRvia the TL;DR App

By: Jesse AbramowitzBlockchain Developer

Ethereum’s latest last fork Constantinople has successfully been integrated into Ethereum and with that comes extra features. This article will cover what the create2 optcode is, why it was added, and what you can do with it. Lastly, I will go through an in-depth demonstration of how to execute it.

Let’s get started!

What is Create2?

This EIP (Ethereum Improvement Proposal) was created by Vitalik on 2018–04–20 and can be found here. Currently there are two types of addresses in Ethereum: wallet addresses and contact addresses. All of these addresses already exist and can have funds sent to them already (there is no button or switch or message required to initiate these account). To create a wallet, a randomly generated private key is required, which will map it to the corresponding public key, then address on chain.

When creating a contract address with the regular create optcode, the address is determined from the address and the nonce of the sender. It would be very dangerous to pre interact with a contract because, (1) the nonce can get out of order and all the funds would be lost and (2) the address is not tied to the contract code so any contract can take that address.

This is what the Create2 optcode can fix. Any contract that is deployed with it can have a deterministic address that is calculated by:

keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]

Since everything there is pre-known a user can calculate it yourself off chain then send the parameters on chain and create the contract.

Why is this important?

With this method users can interact with a contract that does not yet exist. Their funds will be safe at that address and when they are ready, they can deploy a contract that fills that address and interact with those funds.

This solution is secure and (unlike the Create optcode) allows for binding of that address to the initiating contract code.

Use cases

The big use cases for this optcode started in the state channel scalability domain. Specifically with pre-creating and funding contracts before they exist. The whole idea of state channels are to reduce cost. If people can interact with a contract before it exists, then when they are ready to exit the state channel they can create, settle and destroy the contract all in one call, that would significantly reduce the cost.

Anyways, Counterfactual is cool and if you want to read more about it you can start here.

What I always find so great about the crypto and the Ethereum community is how they can turn a slit into a whole. Weird metaphor, but I mean it with utmost admiration. It has been less than a month and people have started theorizing using this optcode for other cool use cases.

For example, James Young from his medium post “One Weird Trick to Fix User On-Boarding” describes how to onboard new users with Create2 in a more seamless way:

Example Steps for Ethereum New User Flow (ENUF)

  1. User generated key pair locally (keys never leave the device)
  2. Key pair used to generate contract address
  3. Funds sent to address prior to contract deployment
  4. Contract deployed after user has funds to at least pay for gas
  5. For novice users, centralize key recovery (ex. Chaperone Wallet Concept)

Let’s Calculate it

Ok, enough talk, let’s see this in action. I found some sample code here. And after some alterations, I was able to deploy it to the rinkeby network here. You can see a transaction which is my factory contract deploying the Create2 contract.

My final outcome looked like this:

We see the factory contract that I deployed first, then we pre-calculate my new contract, we check to make sure it is not on chain (just for our knowledge) we can see false. Then we run the transaction which calls the factory contract’s create2 optcode. That gives us the transaction hash and from that we get the contract address. Now we can check to see if the contract exists on chain and we can see it is true.

The function we are most interested in here it this:

function buildCreate2Address(creatorAddress, saltHex, bytecode) {return `0x${web3.utils.sha3(`0x${[‘ff’,creatorAddress,saltHex,web3.utils.sha3(bytecode)].map(x => x.replace(/0x/, ‘’)).join(‘’)}`).slice(-40)}`.toLowerCase()}

It takes the creator of the contract’s address, a hex of the salt (any random number of certain length) and the init code to create the contract and then it hashes them. This is the same math the EVM does and thus produces the same contract code.

Possible Attack Vectors

Since the generation of the contract address relies on the initcode it is not tied to the constructor which gets called in the contract code at run time. A great explanation of that can be found here.

This means that there is a possible attack where user’s agree on a contract, pre interact with it. Yet this contract has a suicide code in it, and after it is killed, it is redeployed with different inputs for the constructor.

Thus you are re-deploying different code than was thought to be expected. Which can lead to potential poor behaviour.

An example of this was launched in this Reddit thread.

Conclusion

Create2 is an awesome improvement I can’t wait to see what people build with it. Even more, I can’t wait until I can suggest it to a client as the best possible solution and go build something with it myself.

— -

Jesse Abramowitz is a Blockchain Developer at BlockX Labs. He has worked on multiple DApps, projects, and Blockchain Networks. Currently, he is also a professor at George Brown College in Toronto. He is always looking to help, teach and build on the blockchain. You can reach him at: jesse@blockxlabs.com

BlockX Labs specializes in building developer tools and solutions for blockchain ecosystems.We aim to sift through the noise to bring some sense and clarity into the Blockchain space. Our accomplishments include AIWA — a wallet and DApp interaction tool for the Aion Network, and Universal Faucet — a test token faucet for Ethereum, Aion, and Tron.

Follow Us on Twitter: @BlockXLabs


Published by HackerNoon on 2019/03/13