The difference between bytecode and deployed bytecode

João Paulo Morais
Coinmonks
4 min readApr 18, 2022

--

If you inspect the JSON file generated by Remix or Truffle, when compiling a smart contract, you will note that it contains two different bytecodes: bytecode and deployed bytecode. Other IDE may use a different name for one of these bytecodes.

One of them, usually just called bytecode, is the binary code that will be sent to the network for the creation of the smart contract. The other, deployed bytecode, is the binary code that will be stored on the blockchain, and executed every time the contract is invoked.

This way, the bytecode will have more bytes than the deployed bytecode. The (one called) bytecode is a concatenation of the initial code with the deployed bytecode. Let’s start by looking at this, and then explain the purpose of the initial code.

Bytecode and deployed bytecode

Let’s use a simple contract, as below:

pragma solidity ^0.8.7;  contract TestBytecode {         uint public valor;         constructor() {         
valor = 3;
}
function setValor(uint _valor) public {
valor = _valor;
}
}

The only purpose of the contract is to store a variable that can be changed. You can try it on Remix. After compiling, on the contracts/artifacts folder, you will find a file called TestBytecode.json. Inside it, there are two bytecodes, as can be seen in the image below:

One can find the bytecode and the deployedBytecode in Remix.

I will copy and paste the code below. The bytecode is:

608060405234801561001057600080fd5b506003600081905550610133806100286000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c8063428706be146037578063ecbac7cf14604f575b600080fd5b604d600480360381019060499190608c565b6069565b005b60556073565b6040516060919060c1565b60405180910390f35b8060008190555050565b60005481565b60008135905060868160e9565b92915050565b600060208284031215609f57609e60e4565b5b600060ab848285016079565b91505092915050565b60bb8160da565b82525050565b600060208201905060d4600083018460b4565b92915050565b6000819050919050565b600080fd5b60f08160da565b811460fa57600080fd5b5056fea264697066735822122017a6da1fa9164307c08790caa5572a978138abb0de859b5ab8dd35d9976a661b64736f6c63430008070033

The deployed bytecode is:

6080604052348015600f57600080fd5b506004361060325760003560e01c8063428706be146037578063ecbac7cf14604f575b600080fd5b604d600480360381019060499190608c565b6069565b005b60556073565b6040516060919060c1565b60405180910390f35b8060008190555050565b60005481565b60008135905060868160e9565b92915050565b600060208284031215609f57609e60e4565b5b600060ab848285016079565b91505092915050565b60bb8160da565b82525050565b600060208201905060d4600083018460b4565b92915050565b6000819050919050565b600080fd5b60f08160da565b811460fa57600080fd5b5056fea264697066735822122017a6da1fa9164307c08790caa5572a978138abb0de859b5ab8dd35d9976a661b64736f6c63430008070033

Note that the first is larger than the second. Look a little deeper and you’ll note that the first contains the second. To check this, a tip is to look for the first opcode 0xfe. It probably marks the end of the initial code and the beginning of the deployed bytecode. I tagged it in the image below:

The code tagged is the initial code. What is left is the deployed bytecode.

Now let’s look at an even simpler contract.

pragma solidity ^0.8.7;  contract TestBytecodeAgain {      
constructor() {}
}

Two bytecodes are generated. The first is the complete one, which encompasses the initial code and the code that will be stored on the blockchain.

6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220255c2a05777f8a56db0a092845f057844163d0fef9104cafc45164eaf10f2dcd64736f6c63430008070033

The second is just what will be stored on the blockchain.

6080604052600080fdfea2646970667358221220255c2a05777f8a56db0a092845f057844163d0fef9104cafc45164eaf10f2dcd64736f6c63430008070033

As we can see again in the image below, the bytecode contains the initial code and the deployed bytecode.

What is the purpose of the initial code?

A smart contract function that runs only once is its constructor. It is not necessary to store this function on the blockchain as it cannot be executed again. Therefore, its execution is written in the initial code, and not in the deployed bytecode.

In addition, the user can send native currency to the contract as soon as it is created, and so it is necessary to verify that the contract accepts native currency. This check runs at deploy time, and contract creation should revert if the creator sends native currency to a contract that cannot accept native currency.

This shows us that there is a whole script that must be executed only at the time of deploy, and it is this script that is contained in the initial code. That’s why there are two binary codes: the one that must be sent when the contract is created, which contains the initial code, and the one that will be stored on the blockchain.

Thanks for reading!

Photo by Eva Gorobets on Unsplash

Join Coinmonks Telegram Channel and Youtube Channel learn about crypto trading and investing

Also, Read

--

--

João Paulo Morais
Coinmonks

Astrophysicist, full-stack developer, blockchain enthusiast. Technical Writer @RareSkills.