In previous articles of this series, we’ve learned the basics of EVM assembly, as well as how ABI encoding allows the outside world to communicate with a contract. In this article, we’ll see how a contract is created from nothing.

Previous articles of this series (in order).

The EVM bytecode we’ve seen so far is straightforward, just instructions that the EVM executes from top to bottom, no magic up its sleeve. The contract creation process is more fun, in that it blurs the barrier between code and data.

In learning how a contract is created, we’ll see that sometimes data is code, and sometimes code is data.

Put on your favourite wizard hat 🎩

A Contract’s Birth Certificate

Let’s create a simple (and completely useless) contract:

pragma solidity ^0.4.11; contract C {

}

Compile it:

solc --bin --asm c.sol

And the bytecode is:

60606040523415600e57600080fd5b5b603680601c6000396000f30060606040525b600080fd00a165627a7a723058209747525da0f525f1132dde30c8276ec70c4786d4b08a798eda3c8314bf796cc30029

To create this contract, we’ll need to create a transaction by making an eth_sendtransaction RPC call to an Ethereum node. You could use Remix or Metamask to do this.

Whatever deployment tool you use, the parameters for the RPC call would be something similar to:

{

"from": "0xbd04d16f09506e80d1fd1fd8d0c79afa49bd9976",

"to": null,

"gas": "68653", // 30400,

"gasPrice": "1", // 10000000000000

"data": "0x60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00a165627a7a723058204bf1accefb2526a5077bcdfeaeb8020162814272245a9741cc2fddd89191af1c0029"

}

There is no special RPC call or transaction type to create a contract. The same transaction mechanism is used for other purposes as well:

Transferring Ether to an account or contract.

Calling a contract’s method with parameters.

Depending on what parameters you specified, the transaction is interpreted differently by Ethereum. To create a contract, the to address should be null (or left out).

I’ve created the example contract with this transaction:

https://rinkeby.etherscan.io/tx/0x58f36e779950a23591aaad9e4c3c3ac105547f942f221471bf6ffce1d40f8401

Opening Etherscan, you should see that the input data for this transaction is the bytecode produced by the Solidity compiler: