Skip to main content Link Search Menu Expand Document (external link)

History of Callcode and Delegatecall

Callcode opcode

If you read the solidity docs about selfdestruct, you will find a note saying that delegatecall and callcode can provide a way to selfdestruct a contract that does not contain the selfdestruct opcode. What is callcode and how similar is it to delegatecall? callcode is the same as delegatecall but it does not propagate msg.sender or msg.value. callcode was deprecated in Solidity 0.5.0. EIP-2488 proposed to fully deprecate callcode but the EIP did not get far. Even though you will still see the callcode opcode (0xF2) on evm.codes, if you write a contract with the callcode opcode and a solidity version of 0.5.X or newer, you will get an error preventing the contract from compiling with the message TypeError: "callcode" has been deprecated in favour of "delegatecall". Similar cases of deprecated opcodes are found in this table for SWC-111.

Delegatecall opcode

EIP-7 introduced the delegatecall opcode as a bug fix to callcode, which was introduced in the Homestead hard fork in 2016. Because proxy development only started gathering momentum in 2017, callcode was never used for proxies, which is why delegatecall is the opcode that we all associate with proxies today.

Comparison between Callcode and Delegatecall

Below is a diagram comparing proxies built with callcode and delegatecall (Note: it is not recommended to use callcode in proxies).

Comparison with Proxy

Both callcode and delegatecall have the same behavior on storage. That is, both of them can execute the implementation’s code and perform operations with proxy’s storage. The difference between them is in msg.value and msg.sender. In callcode, msg.value can be customized to hold a new value in the implementation contract and msg.sender is changed to Proxy’s address. In delegatecall, both msg.value and msg.sender remain the same in the proxy and implementation contracts.