The to header is normally optional when creating a smart contract… But though reading JSON-RPC documentation, I saw it was possible to set the To field of a transaction creating a smart contract ?

Does the field is ignored in the case of contract creation ? If yes, please quote the source code lines where the recipient is ignored (as an example in a widely used implementation) ? If not what it does since it doesn’t sets contract address ?

3 Answers 3


The actual behavior is described in the Yellow Paper section 4.2. The Transaction:

to: The 160-bit address of the message call’s recipient or, for a contract creation transaction, ∅, used here to denote the only member of B0; formally Tt.

The only possible values for to are:

  • an array of 20 bytes: Indicates a transfer operation.
  • an empty array of bytes: Indicates a contract creation operation.
  • How does Ethereum differentiate between 0x0 and null during contract creation? According to the EVM documentation, all values are initialized. This means to will contain the 0 address as null is not a recognized state. The 0 address links to an external account (which we all know contains a trove of ether and tokens). So, how does ethereum distinguish a contract creation request from a value transfer request originating from sender to address 0x0? Jun 14, 2018 at 2:33
  • Does the content of the data property then determine whether this is a contract creation request, e.g., parser sees to == 0x0 && data == 0x0 and results in value transfer to 0x0. Jun 14, 2018 at 2:43
  • @GViz Probably it is better if you ask a new question about that. Ethereum uses an encoding system called RPL, in this system it is easy to differentiate an empty byte array from an array of 20 zero bytes. Implementations can choose a different internal representation if they see it is better for their needs. For example javascript chooses strings of 40 hexadecimal characters to represent transfers and undefined to represent contract creation (it is unfortunate feature of the language that 0 can be used instead of undefined).
    – Ismael
    Jun 14, 2018 at 3:23
  • Thanks for the info. I didn't think the comment was off-topic, but suppose it is an interesting conversation in its own right. I see that the encoding protocol can distinguish between empty and address. The rules of the EVM are then different and irrelevant here. As you mention, at least entries of 0 & 0x0 no longer send value to the genesis address through web3... github.com/ethereum/web3.js/blob/… Jun 14, 2018 at 3:40
  • I didn't mean it is off-topic but your question is interesting in its own, and you will get better/more answers if you make a new question.
    – Ismael
    Jun 14, 2018 at 4:02

The way you indicate that a transaction is creating a contract is to use an empty to address. This is equivalent to leaving it out in the JSON-RPC interface.

If you set it to something non-empty, the transaction will not create a contract.

  • Where is source code stating that? Jun 8, 2018 at 7:42
  • As the other answer indicated, the definitive source for how this works is the Yellow Paper. Any Ethereum node software will need to implement this. If you specify which software you're interested in, there's a chance someone who knows that codebase will be able to find where this is implemented in that code.
    – user19510
    Jun 8, 2018 at 7:46
  • I’m not interested in a specific software, but I just want an example in a widely used implementation. Jun 8, 2018 at 8:11
  • I'm not sure why you're asking for that. Do you not understand the answers you've received? Or do you not believe them?
    – user19510
    Jun 8, 2018 at 8:12
  • 1
    github.com/ethereum/go-ethereum/blob/master/core/types/… makes a few mentions of this (search for "creation"). Not sure what kind of code you're looking for.
    – user19510
    Jun 8, 2018 at 8:16

This is only relative to the ᴊꜱᴏɴ-ʀᴘᴄ protocol : In order to get a transaction treated as contract creation, to must be unset as shown by go-ethereum :

func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) {
    if err = st.preCheck(); err != nil {
    msg := st.msg
    sender := vm.AccountRef(msg.From())
    homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber)
    contractCreation := msg.To() == nil

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.