What is address(0) in Solidity

Solution 1:

Within an Ethereum transaction, the zero-account is just a special case used to indicate that a new contract is being deployed. It is literally '0x0' set to the to field in the raw transaction.

Every Ethereum transaction, whether it's a transfer between two external accounts, a request to execute contract code, or a request to deploy a new contract, are encoded in the same way. A raw transaction object will look something like this:

transaction = {
  nonce: '0x0', 
  gasLimit: '0x6acfc0', // 7000000
  gasPrice: '0x4a817c800', // 20000000000
  to: '0x0',
  value: '0x0',
  data: '0xfffff'
};

If to is set to something other than '0x0', this request will result in transferring ether to the address (if value is non-zero), and execute the function encoded in the data field. Remember, the address can either be a contract or an external account.

When the to address is the zero-address, a new contract will be created by executing the code in data (this is what is meant by "code that returns the code"). The address of the newly created contract is technically known beforehand as it's based on the address of the sender and it's current nonce. That address becomes the official address of the contract after mining.

For a pretty good read on Ethereum transactions, check out this blog post.

Note: There is also the actual Solidity code statement address(0) which is the initial value of a variable of type address. The documentation you posted, however, is referring to specifically when the to account address in a transaction is set to '0x0'.

Solution 2:

It's not actually true that a contract creation transaction has a "to" field set to the zero address (meaning 0x00...000). This is an easy mistake to make (and I've made it too) as it is described that way in many resources.

The passage you cite from the Solidity docs were updated to state this:

If the target account is not set (the transaction does not have a recipient or the recipient is set to null), the transaction creates a new contract. As already mentioned, the address of that contract is not the zero address but an address derived from the sender and its number of transactions sent (the “nonce”).

So you can see they realized at some point that the recipient field should be empty. I've actually looked at serialized creation transactions and found 0x80 there instead of an RLP-ed zero address.

In fact, 0x80 is the RLP encoding of an empty byte array, which is what the Yellow Paper states is the recipient for a contract creation:

The address hash $T_t$ is slightly different: it is either a 20-byte address hash or, in the case of being a contract-creation transaction (and thus formally equal to ∅), it is the RLP empty byte sequence and thus the member of $B_0$

As I said, this is a common source of confusion. In that vein, this GitHub PR rolling back a mistakenly "fixed" test is amusing. It has the comment:

RLP encoding of 0 is encoding of empty byte array, so 0x80 is correct.

0x00 is encoding of byte array of length 1 containing one byte 0, not encoding of integer 0.