2

What I'd like to do is analyze all the opcodes that are executed when I call a contract, or call a function from a contract.

According to my understanding, this computation would happen on my own machine, in the EVM, and only the result would be sent to the blockchain.

My idea is that, for this result to be calculated, the computations have to run on my local machine at some point in the following process:

var contractAbi = eth.contract([{"constant":true,"inputs":[],"name":"getPeople","outputs":[{"name":"","type":"bytes32[]"},{"name":"","type":"bytes32[]"},{"name":"","type":"uint256[]"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_firstName","type":"bytes32"},{"name":"_lastName","type":"bytes32"},{"name":"_age","type":"uint256"}],"name":"addPerson","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"people","outputs":[{"name":"firstName","type":"bytes32"},{"name":"lastName","type":"bytes32"},{"name":"age","type":"uint256"}],"payable":false,"type":"function"}]);

undefined

var myContract = contractAbi.at("0xC127E3ca071892B1b471b4FC568312Fcbb737879");

undefined

var getData = myContract.addPerson.getData("S. Matthew", "English", 28);

undefined

personal.unlockAccount(eth.coinbase, 'hunter2');

web3.eth.sendTransaction({to:"0xC127E3ca071892B1b471b4FC568312Fcbb737879", from:"0xd7a9a61a480d458a1181e0563b07f944df4489a6", data: getData, gas: (270000)});

"0x0cec118d22fbd572bf25c7e4143919e608989bec7da08512f2a6f3171df3b3b8"

myContract.address

"0xC127E3ca071892B1b471b4FC568312Fcbb737879"

myContract.getPeople()

[["0x532e204d61747468657700000000000000000000000000000000000000000000"], ["0x456e676c69736800000000000000000000000000000000000000000000000000"], [28]]

myContract.getPeople().toLocaleString()

"0x532e204d61747468657700000000000000000000000000000000000000000000,0x456e676c69736800000000000000000000000000000000000000000000000000,28"

How can I observe the opcodes that are being executed as a consequence of the above sequence?

Using the ByteCode To Opcode Disassembler on Etherscan I've seen which opcodes are invoked on contract creation, but I imagine that this is different than just calling a contract or one of it's functions, since- for instance, you won't need to invoke the constructor again, etc.

enter image description here

1 Answer 1

2

Use debug.traceTransaction(...).

Example from Mainnet:

> debug.traceTransaction("0xe7cdf3ddebd6b1f3c21b26346da52901b6035b39bdfb58de49491b47a92808a7")
{
  gas: 30981,
  returnValue: "",
  structLogs: [{
      depth: 1,
      error: null,
      gas: 13725,
      gasCost: 3,
      memory: null,
      op: "PUSH1",
      pc: 0,
      stack: [],
      storage: {}
  }, {
      depth: 1,
      error: null,
      gas: 13722,
      gasCost: 3,
      memory: null,
      op: "PUSH1",
      pc: 2,
      stack: ["0000000000000000000000000000000000000000000000000000000000000060"],
      storage: {}
  }, {
  ...
  }, {
      depth: 1,
      error: null,
      gas: 4019,
      gasCost: 1,
      memory: ["0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000060", "000000000000000000000000000000000000000000000000015a1fa6f11a5551"],
      op: "JUMPDEST",
      pc: 80,
      stack: ["00000000000000000000000000000000000000000000000000000000f7654176"],
      storage: {}
  }, {
      depth: 1,
      error: null,
      gas: 4019,
      gasCost: 0,
      memory: ["0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000060", "000000000000000000000000000000000000000000000000015a1fa6f11a5551"],
      op: "STOP",
      pc: 81,
      stack: ["00000000000000000000000000000000000000000000000000000000f7654176"],
      storage: {}
  }]
}
5
  • so, it doesn't cost any gas to run that? I can do it for any transaction? where does it get that data from? Commented Aug 7, 2017 at 16:48
  • 1
    It does not cost gas to run. You can do it for any transaction as long as your geth blockchain data contains the full transaction data. If you --fast sync your blockchain, the full transaction data will be unavailable before the block that is fast synced. See also ethereum.stackexchange.com/questions/4282/… and ethereum.stackexchange.com/questions/6007/… Commented Aug 7, 2017 at 16:51
  • so then there's just like- hundreds of thousands, even millions, of JSON objects on every full node with all this opcode data on them? Commented Aug 7, 2017 at 16:54
  • ah so, sort of relatedly, we could probably call this function in a more specialized way, for instance- only to get the opcodes, leave the rest of that stuff, isn't it? Commented Aug 7, 2017 at 16:56
  • haha ok- last question for these comments- is it possible to see how long each opcode takes to execute? Commented Aug 7, 2017 at 18:38

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.