How Smart Contract Deployment Works

[This blog post explains a little bit about how smart contract deployment works in an Ethereum network, but it is not necessary for learning Solidity programming. We write it for those of you who’d like a little deeper understanding of what is going on when a smart contracts are deployed.]

In our How Ethereum Transactions Work post, we described the essential elements of a transaction message in an Ethereum network and how they work. This post will similarly describe how smart contracts are initially deployed to the network.

Smart Contract Deployments Are Transactions

The Ethereum network has only one transaction mechanism, which is overloaded to handle three distinct kinds of transactions:

  1. A simple ether transfer to an externally owned account
  2. Invocation of code associated with a previously deployed smart contract (and possibly an ether transfer)
  3. Deployment of a smart contract (and possibly an ether transfer to the corresponding deployed contract)

Contract deployment is by far the most subtle operation. To understand it, let’s review the components of a transaction message:

  • recipient
  • value
  • data
  • gas limit
  • gas price
  • nonce
  • signature

For contract deployment, there is nothing unique about the value (attached ether), the gas limit and price, the nonce, or the signature. The recipient and the data, however, are special:

  • recipient For contract deployment, the recipient address is 0. This signifies that the transaction creates a contract.
  • data For contract deployment, the data field holds code to be executed during deployment.

Contract Initialization

The data field of a contract deployment transaction is code to be executed during contract initialization. It is not the code that is executed on subsequent transactions sent to the contract. That code is returned by the initialization code. Essentially, the code in the data field is a program that is going to write a program that gets deployed as a smart contract. Although that sounds fairly open-ended and complex, in practice it is typically quite straightforward. The standard initialization code generated by the Solidity compiler does the following:

  1. Runs the code in the contract’s constructor, setting storage values, etc.
  2. Copies the code for the rest of the contract into memory and returns it.

The code to be copied is simply appended to the constructor’s code in the data field.

Constructor parameters are handled similarly. They are stored last in the data field, and the initialization code reads them from there.

The Address of the Deployed Contract

Once a contract is deployed, it is referenced by its address, which is guaranteed to be unique. Computing the address requires only the address of the sender account and the sender’s nonce. Per Section 7, “Contract Creation,” of the Ethereum yellow paper:

The address of the new account is defined as being the rightmost 160 bits of the Keccak hash of the RLP encoding of the structure containing only the sender and the nonce.

Externally owned accounts have nonces that start at zero and increase with each transaction. Contracts can also deploy other contracts, so they also need to have nonces. Per EIP-161, contracts start with a nonce of 1. This is a fairly recent change, so you may still see older deployed contracts with nonces of 0.1 The nonce for a contract account only increases when it deploys a new contract. “Internal transactions” (when a contract calls into another contract or transfers ether) do not increase the contract’s nonce.

Summary

  • Contract deployment is a special Ethereum transaction sent to the address 0.
  • The deployment has the side effects of creating bytecode at a specific address (i.e, it creates a smart contract account).
  • Contracts are deployed at predictable addresses based on the address and nonce of the account creating the contract.

Resources

An excellent, although much more detailed, explanation can be found in Diving Into The Ethereum VM Part 5 — The Smart Contract Creation Process.

The definitive explanation is in the Ethereum yellow paper.


  1. On some test networks, the nonce starts at a different value (to avoid replay attacks between networks). So it would be more accurate to say that contract nonces start at n+1, where n is the initial nonce for an account.