Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What does the VM do to code before putContractCode is called #289

Closed
skilesare opened this issue Mar 14, 2018 · 6 comments
Closed

What does the VM do to code before putContractCode is called #289

skilesare opened this issue Mar 14, 2018 · 6 comments

Comments

@skilesare
Copy link

I used an example I found(#128) to deploy code using vm.runTX

The code is super simple. Solidity:

pragma solidity ^0.4.15;


contract TestTime {

function ayear() constant returns (uint256){
  return 1 years;
}

}

Remix outputs this as the code:

code = "0x60606040523415600e57600080fd5b60a28061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063257c8c89146044575b600080fd5b3415604e57600080fd5b6054606a565b6040518082815260200191505060405180910390f35b60006301e133809050905600a165627a7a723058202e0505c5235858e9b30b642de84fb21c102bdd86b3f7dfbdda1a1f80fb90fd900029"

I added a console.log to the saveCode method of the runCall function to output exactly what was being written to the chain:

console.log('saving this code:')
console.log(vmResults.return.toString('hex'))

It outputs the following code:
0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063257c8c89146044575b600080fd5b3415604e57600080fd5b6054606a565b6040518082815260200191505060405180910390f35b60006301e133809050905600a165627a7a723058202e0505c5235858e9b30b642de84fb21c102bdd86b3f7dfbdda1a1f80fb90fd900029

It looks like 23 bytes "3415600e57600080fd5b60a28061001c6000396000f3006060604052" are taken out of the code when it is written to the tree.

The reason I need this I'm trying to sideload some code and storage into the evm without having to run the transactions.

I tried directly loading the original code with

vm.stateManager.putContractCode "ca35b7d915458ef540ade6068dfe2f44e8fa733c", codeHex ,(contractError, contractTx) =>

When I do this and then run the code the return ends up being the original code!

If I switch out to the code with the missing 23 bytes it works like a champ. What am I missing about these 23 bytes? Are they the opcode that saves the code to the blockchain? If so, how do I remove them when I'm trying to move code from remix? Will they always be the same so I can just find replace?

What am I missing?

@skilesare
Copy link
Author

I may have answered my own question.

Looks like I need the 'runtime bytecode' section instead of the 'bytecode' section. Would still love to hear what the differences are conceptually id anyone has any insight.

@skilesare
Copy link
Author

The other thing I had to do to get this to work was to uncomment the following line from the stageManager.putAccount function. Not sure why it was commented out.

self.trie.put(addressHex, account.serialize(), cb)
//cb()

@holgerd77
Copy link
Member

For reference for everyone who wants to dig into this: the line mentioned above is still commented out, have no first-sight context though.

@holgerd77
Copy link
Member

Another update: line in StateManager.putAccount() still commented out, updated with the new reference link working in the monorepo context with changed paths.

@jochem-brouwer
Copy link
Member

@skilesare Just as an explanation here: the original code here (so with the 23 bytes) is the code you need to run on the blockchain to create the contract. To create a contract, the "creation code" (so with the 23 bytes) is being ran, which puts the code (calldata) minus the first 23 bytes (this is the "deployment code" which we don't need if we call the contract) in memory (using CODECOPY; if you create a contract the calldata is temporarily in the in the current contracts' CODE so you can CODECOPY it to memory) and then RETURNs this data from memory. The returned data is then put as the contracts' code on the chain. This is (and should be) the same as solidity's runtime code.

I think this issue can be closed? @holgerd77

holgerd77 added a commit that referenced this issue Mar 11, 2021
@holgerd77
Copy link
Member

Will close here as suggested by @jochem-brouwer, thanks for this detailed explanation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants
@evertonfraga @skilesare @holgerd77 @jochem-brouwer and others