33

I constantly see different types of bytecode and do not know what each of them are. What are the differences between bytecode, init code, deployed bytecode, creation bytecode, and runtime bytecode?

2 Answers 2

55

I wrote an article that goes over this information in depth. I will summarize it here.


tl;dr - There are only two types of bytecode on Ethereum but five different names to describe them.

Creation Bytecode

This is the code that most people are referring to when they say bytecode. This is the code that generates the runtime bytecode—it includes constructor logic and constructor parameters of a smart contract. The creation bytecode is equivalent to the input data of the transaction the creates a contract, provided the sole purpose of the transaction is to create the contract.

When you compile a contract, the creation bytecode is generated for you. A truffle-generated ABI refers to the creation bytecode as bytecode (*). This is also the bytecode that is shown when clicking "compilation details" for a contract on Remix.

This code can be retrieved on-chain using type(ContractName).creationCode.

Creation bytecode can be retrieved off-chain by the getTransactionByHash JSON RPC call.

(*) The bytecode generated by Truffle corresponds to the creation bytecode minus the constructor arguments (as Truffle does not know them at compilation time). The creation bytecode is therefore equal to the Truffle bytecode concatenated with some bytes containing the information of the constructor arguments. For example, if the constructor takes the uint256 "123" and the bool "true" as arguments, the resulting creation code, passed as the data parameter of the deployment transaction, will be : Truffle generated bytecode + "000000000000000000000000000000000000000000000000000000000000007b" + "0000000000000000000000000000000000000000000000000000000000000001". For dynamic types such as string, bytes, and array, the encoding is more complex.

Runtime Bytecode

This is the code that is stored on-chain that describes a smart contract. This code does not include the constructor logic or constructor parameters of a contract, as they are not relevant to the code that was used to actually create the contract.

The runtime bytecode for a contract can be retrieved on-chain by using an assembly block and calling extcodecopy(a). The hash of the runtime bytecode is returned from extcodehash(a). This opcode was introduced with EIP 1052 and included in the Constantinople hard fork.

The runtime bytecode can also be retrieved on-chain by using Solidity's type information. The Solidity code to retrieve the bytecode is type(ContractName).runtimeCode.

Finally, this code is returned by the JSON RPC call, getCode.

Bytecode

This should be used as the umbrella term that encompasses both runtime bytecode and creation bytecode, but it is more commonly used to describe the runtime bytecode.

Deployed Bytecode

This term is used exclusively by truffle-generated ABIs and refers to a contract's runtime bytecode. I have not seen it used outside of these files.

Init Code

This code is the same as the creation bytecode. It is the code that creates the bytecode that is stored on-chain.  This term is commonly used in articles referring the the bytecode needed when using the create2 opcode. 

Conclusion

It is my opinion that the only terms that should be used are runtime bytecode and creation bytecode, as they are explicitly describing what the code is. I believe bytecode should be an umbrella term that includes both of these aforementioned term.

5
  • 2
    Nice tl;dr write up. I thank you for it! Mar 25, 2020 at 10:36
  • 1
    Do you know if there's a way to retrieve creationCode through assembly commands? Maybe manipulating somehow the Runtime Bytecode given back by the extcodecopy(a) call? Nov 17, 2020 at 9:33
  • any way I can get the creation bytecode off-chain? I think it is possible since the creation bytecode is generated before the contract-creation transaction, but I don't know how to do it.
    – DiveInto
    May 3, 2021 at 3:37
  • "Creation Bytecode This is the code that most people are referring to when they say bytecode." I think when people saying bytecode they mostly refer to runtime bytecode.
    – cifer
    Jan 21 at 8:42
  • Does Etherscan return the creation or the runtime bytecode? May 17 at 11:10
1

For those familiar with Javascript, this example might help. Imagine that the blockchain stored JavaScript and that we want to deploy a contract with this function:

function hi() { return "hi" }

(Recall that a contract is created by sending a transaction to address 0.) We may think that to do this we would send a transaction with just the "runtime code" in the transaction's data (Etherscan calls "Input Data"):

to: 0
data: `function hi() { return "hi" }`

However, that's not how the EVM is specified, see Yellow Paper below, so the transaction will have "creation / init code" that looks more like this:

to: 0
data: 
`(function() {
    return 'function hi() { return "hi" }';
}());`

The specification from the Yellow Paper https://ethereum.github.io/yellowpaper/paper.pdf is:

init: An unlimited size byte array specifying the EVM-code for the account initialisation procedure, formally Ti. init is an EVM-code fragment; it returns the body, a second fragment of code that executes each time the account receives a message call (either through a transaction or due to the internal execution of code). init is executed only once at account creation and gets discarded immediately thereafter.

JS example above from Bytecode on block chain different from the one used when deploying

Your Answer

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

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