The Ethereum JSON-PRC spec contains an eth_getCode method, but it is not specified what is being retrieved:
- Init bytecode (including constructor)
- Deployed bytecode (without constructor)
Which one is it?
bytecodejson-rpc
The Ethereum JSON-PRC spec contains an eth_getCode method, but it is not specified what is being retrieved:
Which one is it?
Here are some libraries for interacting with an Ethereum node. They are grouped by language, and roughly according to their last commit, with any appropriate brief notes. Javascript has been included since they are alternatives to web3.js and provide value to the overall list.
https://github.com/AugurProject/ethrpc with IPC support, last commit 1 day ago
https://github.com/tarrencev/ethjs written in ES6, RPC calls return a promise/stream, last commit 10 days ago
https://github.com/ConsenSys/ethjsonrpc all 62 JSON-RPC methods, last commit 11 days ago
https://github.com/pipermerriam/ethereum-rpc-client RPC, last commit Jan 2 2016
https://github.com/pipermerriam/ethereum-ipc-client IPC, last commit Jan 4 2016
https://github.com/LawrenceBotley/EthereumRpc-NET appears to have majority of RPC done, last commit Dec 13 2015
https://github.com/tymat/ethereum-ruby appears to be minimal and from 2 years ago
For other languages, general JSON-RPC libraries are available as a starting point.
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.
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.
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
.
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.
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.
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.
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
The command
eth_getCode
returns the bytecode associated with the address in the Ethereum world state, that will be the deployed bytecode (or runtime bytecode).The init bytecode could be obtained from the deployment transaction's data field, unless it was created by a contract in which case you have to trace the transaction to obtain the details.