16

When I deploy a contract from node.js using the web3 JavaScript API (connected to a locally running geth), and then check the deployed bytecode using eth.getCode(address) (either from the JS console or in node, both connected to a locally running geth), the deployed code sometimes differs from the code that was used when deploying (the former is a trailing substring of the latter, i.e. missing some data at the beginning).

Is this normal? Why does this happen?

The deployed contract works as expected though.

The script used for deploying is something like this:

web3.eth.contract(abi).new({from: addr, data: originalBin, gas: 4700000})

I am deploying a ETH/ETC splitter contract similar to this.

Eg. this bytecode:

6060604052732bd2326c993dfaef84f696526064ff22eba5b362600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550610163806100516000396000f36060604052361561003d576000357c010000000000000000000000000000000000000000000000000000000090048063d264e05e1461004a5761003d565b6100485b610002565b565b005b610057600480505061006f565b60405180821515815260200191505060405180910390f35b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166316c72721604051817c01000000000000000000000000000000000000000000000000000000000281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015015801561014d575073901e93811ef02ce5e34b6f4ac2722a3ed6a1501273ffffffffffffffffffffffffffffffffffffffff16600034604051809050600060405180830381858888f193505050505b1561015b5760019050610160565b610002565b9056

got deployed at 0xde8e581f96707add7ebbeb678a0ba36778b96540 as:

0x6060604052361561003d576000357c010000000000000000000000000000000000000000000000000000000090048063d264e05e1461004a5761003d565b6100485b610002565b565b005b610057600480505061006f565b60405180821515815260200191505060405180910390f35b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166316c72721604051817c01000000000000000000000000000000000000000000000000000000000281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015015801561014d575073901e93811ef02ce5e34b6f4ac2722a3ed6a1501273ffffffffffffffffffffffffffffffffffffffff16600034604051809050600060405180830381858888f193505050505b1561015b5760019050610160565b610002565b9056

Edit: added bytcode examples

1
  • Can you add examples of bytecodes to the question? Commented Aug 4, 2016 at 14:34

1 Answer 1

14

Yes, it is normal and the code on the blockchain is always a subset of the compiled (byte)code, because the compiled code includes initialization code. The compiled code is/executes a function which returns the blockchain code, but as part of the execution also initializes the contract being deployed.

For your contract, look at its transaction 1 and you can see the invocation data, the payload and the return value. The compiled code is the payload, and executing it produces the return value.

enter image description here

Related: How can I verify that a contract on the blockchain matches the source code?


To help explain above, the following is for illustration purposes only. Imagine that the blockchain stored JavaScript and that we want to deploy this function:

function hi() { return "hi" }

(Recall that a contract is created by sending a transaction to address 0.) We may think that to do this we would send a transaction with the basic details:

to: 0
data: `function hi() { return "hi" }`

However, that's not how the EVM is specified and the transaction needs to look more like this:

to: 0
data: 
`(function() {
    return 'function hi() { return "hi" }';
}());`

This shows what's meant by the return bolded above, but to see initialization, it may be clearer to study actual bytecode.


For reference, the specification from the Yellow Paper https://ethereum.github.io/yellowpaper/paper.pdf explains it as:

init: An unlimited size byte array specifying the EVM-code for the account initialisation procedure, formally Ti. init is an EVM-code fragment; it returns the body, a second fragment of code that executes each time the account receives a message call (either through a transaction or due to the internal execution of code). init is executed only once at account creation and gets discarded immediately thereafter.

2
  • It seems redeploying a contract using bytecode on the blockchain is not possible (assuming ABI is known). If it is possible to reconstruct and redeploy with information already extant on the chain, let me know and I'll open a new question. Commented Oct 5, 2018 at 3:59
  • 1
    @Gviz: I added an illustration to help explain the idea more to others. I think it is worthwhile to ask your question anew.
    – eth
    Commented Oct 6, 2018 at 6:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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