Evm

geth 控制台標誌/選項,用於輸出在呼叫合約或函式呼叫時執行的所有操作碼

  • August 7, 2017

我想做的是分析呼叫合約或從合約呼叫函式時執行的所有操作碼。

根據我的理解,這個計算會在我自己的機器上進行EVM,並且只有結果會被發送到區塊鏈。

我的想法是,為了計算這個結果,計算必須在以下過程中的某個時間點在我的本地機器上執行:

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"

我如何觀察由於上述序列而正在執行的操作碼?

在 Etherscan 上使用ByteCode To Opcode Disassembler我已經看到在創建合約時呼叫了哪些操作碼,但我認為這與僅呼叫合約或其函式之一不同,因為例如,您不需要呼叫再次建構子,等等。

在此處輸入圖像描述

使用debug.traceTransaction(...).

來自主網的範例:

> 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: {}
 }]
}

引用自:https://ethereum.stackexchange.com/questions/23830