Does Etherscan display the Creation Code or Runtime Code of a Contract?
This is gonna be a quick short post on some findings regarding how etherscan displays the bytecode of a deployed and verified smart contract.
After we deploy a contract on the ethereum blockchain, we know for a fact that the creation code(init code) is executed and it returns the runtime bytecode which is then stored on-chain.
It must be noted that only the runtime bytecode of a smart contract is stored on-chain for further execution of the smart contract.
However, here is a quick question:
When we deploy a smart contract on Ethereum and verify it on Etherscan, what exactly is the bytecode that is attached to the verified contract?
A very intuitive answer to this question is the Runtime Bytecode because that's the portion of bytecode that is stored on-chain. Therefore, its easier to assume that etherscan displays just the runtime bytecode.
Well, that does not seem to be the case.
So the question remains - the bytecode that we see on etherscan, What exactly is it?
- Is it the entire bytecode, i.e., (Creation code + Runtime Code)?
- Or, Is it just the Runtime code?
- Or, Is it Runtime + Constructor arguments only?
Let's do a quick experiment to figure this out.
A Quick Experiment
We gonna deploy 2 different contracts:
- First one without any constructor arguments, and
- Second one with constructor arguments
First Deployment: Without Constructor Arguments
We use the following Test Contract 👇
Actual Creation Code
608060405234801561001057600080fd5b50606460008190555061017f806100286000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea264697066735822122095cb79f37fbcae031f3faea184aa57e0c8cd49ed26e7a6d17a48cf3858e56d9f64736f6c63430008110033
Actual Runtime Code
608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea264697066735822122095cb79f37fbcae031f3faea184aa57e0c8cd49ed26e7a6d17a48cf3858e56d9f64736f6c6343000811003300
Etherscan's Bytecode After Contract Verification
608060405234801561001057600080fd5b50606460008190555061017f806100286000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea264697066735822122095cb79f37fbcae031f3faea184aa57e0c8cd49ed26e7a6d17a48cf3858e56d9f64736f6c63430008110033
Second Deployment: With Constructor Arguments
We use the following Test Contract 👇 and pass 1000 as the argument.
Actual Creation Code
0x608060405234801561001057600080fd5b506040516102353803806102358339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b61017f806100b66000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220e258c2c50f60615be13c1352bb92ad8365dcb6b971ca21882a504f1beb4167fc64736f6c6343000811003300000000000000000000000000000000000000000000000000000000000003e8
Actual Runtime Code
608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220e258c2c50f60615be13c1352bb92ad8365dcb6b971ca21882a504f1beb4167fc64736f6c6343000811003300
Etherscan's Bytecode After Contract Verification
608060405234801561001057600080fd5b506040516102353803806102358339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b61017f806100b66000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220e258c2c50f60615be13c1352bb92ad8365dcb6b971ca21882a504f1beb4167fc64736f6c6343000811003300000000000000000000000000000000000000000000000000000000000003e8
Findings
After the above deployments and bytecode comparisons of the actual bytecode and etherscan's bytecode, here are the findings that I came across:
- Although the Runtime code is the only part of the bytecode that is stored on-chain, etherscan doesn't display just the runtime code.
- Etherscan displays the entire bytecode (Init Code + Runtime Code) of the smart contract appended with the constructor arguments at the end, if they exist.
So technically etherscan displays:
Init Code (executed during contract deployment ) + Runtime Code (part that is stored on-chain) + Constructor Arguments
An additional detail: The bytecode of smart contracts that are not verified yet on Etherscan is just the runtime bytecode.