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

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: {}
  }]
}
  • so, it doesn't cost any gas to run that? I can do it for any transaction? where does it get that data from? – smatthewenglish Aug 7 '17 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/… – The Officious BokkyPooBah Aug 7 '17 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? – smatthewenglish Aug 7 '17 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? – smatthewenglish Aug 7 '17 at 16:56
  • haha ok- last question for these comments- is it possible to see how long each opcode takes to execute? – smatthewenglish Aug 7 '17 at 18:38

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.