TL;DR
bin-runtime
is the code that is actually placed on the blockchain. The regular bin
output is the code placed on the blockchain plus the code needed to get this code placed on the blockchain, the code of the constructor.
Longer answer
The basics of the Ethereum Virtual Machine is defined in Section 9.1 of the Ethereum Yellow Paper.
To answer this question fully, you must first know how a smart contract is created. A smart contract is created by sending a transaction with an empty "to" field. When this is done, the Ethereum virtual machine (EVM) runs the bytecode which is set in the init byte array[1] which is a field that can contain EVM bytecode -- the binary code for executing logic on Ethereum. The EVM bytecode that is then stored on the blockchain is the value that is returned by running the content of init on the EVM. The bytecode can refer to itself through the opcode CODECOPY
. This transfers the currently running bytecode to the EVM memory. The CODECOPY
opcode reads three values on the stack where two of those values are pointers to the bytecode, one marking the beginning and one marking the end of what should be copied to memory. The RETURN
opcode is then used, along with the correct values placed on the stack, to return bytecode from the initial run of the EVM code. RETURN
reads and removes two pointers from the stack. These pointers define the part of the memory that is a return value. The return value of the initial contract creating run of the bytecode defines the bytecode that is stored on the blockchain and associated with the address on which you have created the smart contract.
The code that is compiled but not stored on the blockchain is thus the code needed to store the correct code on the blockchain but also any logic that is contained in a (potential) constructor of the contract.
The bin-runtime argument can be used to verify that some specific Solidity source code is placed on a specific address. Compiling the source code that a person claims represents the smart contract on an address on the blockchain and comparing that to the binary code that is actually stored on the address eth.getCode(contractaddress)
means that you can be sure what the source code for the contract is.
See the Ethereum Yellow Paper, section 4.3 for how smart contracts are created.
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.
Best Answer
According to hardhat document :
deployedBytecode: A "0x"-prefixed hex string of the unlinked runtime/deployed bytecode. If the contract is not deployable, this has the string "0x"
. It means deployed bytecode is runtime bytecode.runtime bytecode
and its initial environment (e.g. state storages, including running the constructor logic).deployedBytecode
orruntime bytecode
is what you see on etherscan or when you queryeth_getCode
using ethereum node's RPC: Does "eth_getCode" return the init bytecode or the deployed bytecode?Hope the above helps, you can read more about that here Difference between bytecode and runtime bytecode