2

Possible outputs of the Solidity compiler include creation bytecode and deployed (runtime) bytecode. However, this compiled deployed bytecode might not be the same as the one that will actually be deployed on the blockchain. This might be the case if the contract requires constructor arguments to initialize immutable variables. So, how do I use the mentioned artifacts (creation bytecode, deployed bytecode, constructor arguments) and generate the actual deployed bytecode, without actually deploying it. One possible option is to deploy to a (local) testnet and then see the deployed bytecode, but this seems like an overkill.

Ok, to make things clearer, this is the nomenclature (I didn't make it up: What is the difference between bytecode, init code, deployed bytedcode, creation bytecode, and runtime bytecode?):

deployed bytecode = runtime bytecode

actual deployed bytecode = actual runtime bytecode

This question concerns the fact that it is sometimes the case that:

deployed bytecode (as predicted by compilation) =/= actual deployed bytecode (after deployment)

In fact, the last formula generally holds when a contract uses immutable variables.

2

This GitHub issue helped me find the answer. Basically what I needed can be achieved with the ethereumjs-vm module:

const VM = require("ethereumjs-vm").default;
const BN = require("bn.js");
const vm = new VM();

vm.runCode({
    code: Buffer.from(creationBytecode + abiEncodedConstructorArguments, "hex"),
    gasLimit: new BN(...),
}).then(results => {
    const actualDeployedBytecode = results.returnValue.toString("hex");
    console.log(actualDeployedBytecode);
});
0

The bytecode generated after compilation is not the same as the creation bytecode used for the data parameter of the deployment transaction, as constructor arguments are not known at compilation time.

You can think of the creation bytecode as something which runs the constructor to initialize the smart contract state and returns the runtime bytecode stored on the blockchain.

However the runtime bytecode does not depend on the constructor part and only reflects the smart contract code. You can take the deployedBytecode returned by Truffle in the JSON file generated after compilation, it is the same as the runtime bytecode stored on-chain.

2
  • The runtime bytecode does depend on constructor arguments if it uses immutable variables. This is precisely why I've asked the question. – FabijanC Mar 9 at 8:12
  • You are correct. As you didn't mention the use of immutable variables in your first post (before the edit), I though of a "classic case". This answer does not apply in the specific case of immutable variables. – clement Mar 9 at 9:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.