1. Background
OEC is fully compatible with the deployment and operation of Ethernet contracts. For complex contracts, developers need to understand the execution process in order to debug the contracts and efficiently locate contract problems.
2. Problems
At present, the OEC test network and the main network do not provide the function of viewing contract tracing, nor does the browser provide tracing information.
3. Solutions
3.1. Description and limitations
In the current solution, the trace function requests the OEC node to re-execute the specified transaction and returns the log of the execution.
If an OEC node wants to re-execute a transaction and return the exact same result as before, it needs the historical status of the transaction, all metadata of the block it is in, and the status of all previous transactions in the same block.
Therefore, depending on node synchronization and clipping mechanisms, different trace results may occur:
- Nodes containing full data archives can trace any transaction at any time.
- Nodes that are started with snapshots and do not have clipping (pruning=nothing) can only trace transactions whose height is greater than the snapshot height.
- If a node has pruning enabled, it will not be able to trace transactions that have been pruned.
- For more details on the pruning configuration, please refer to https://forum.okt.club/d/193-pruning
3.2. Configuration and Usage
3.2.1. Configure the node to enable trace function
When the node is started, the following parameters can be configured for the trace function.
--debug-api=true
Where, --debug-api is enabled or not, the default is false, i.e. the function is not enabled.
3.2.2. Viewing trace information
3.3.2.1. Reference description
disableStack default is false, if set to true, then the return log will no longer contain the Stack field.
disableStorage defaults to false, if set to true, then the returned log will no longer contain the Storage field.
disableMemory defaults to false, if set to true, then the return log will no longer contain the Memory field.
disableReturnData defaults to false, if set to true, the return log will no longer contain the ReturnData field.
tracers default to empty, i.e. use StructLogger to record the full amount of trace logs.
- Pre-created scripts can be configured, see https://github.com/ethereum/go-ethereum/tree/master/eth/tracers/js/internal/tracers for supported scripts
- Custom javaScript scripts can also be configured. See https://geth.ethereum.org/docs/rpc/ns-debug#debug_tracetransaction for syntax
- If the tracer field is not empty, all disable fields are ignored.
3.3.2.2. Configuration examples
3.2.2.2.1. Disable configuration
Input:
$ curl -H "Content-Type: application/json" -d '{"id": 1, "method": "debug_traceTransaction", "params": [" 0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f", {"disableStack": true, "disableMemory": true, "disableStorage": true}]}' localhost:8545
Output:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"failed": false,
"gas": 21449,
"returnValue": "",
"structLogs": [
{
"depth": 1,
"gas": 42749,
"gasCost": 3,
"op": "PUSH1",
"pc": 0
},
{
"depth": 1,
"gas": 42746,
"gasCost": 3,
"op": "PUSH1",
"pc": 2
},
...
...
...
{
"depth": 1,
"gas": 21301,
"gasCost": 1,
"op": "JUMPDEST",
"pc": 154
},
{
"depth": 1,
"gas": 21300,
"gasCost": 0,
"op": "STOP",
"pc": 155
}
]
}
}
3.2.2.2.2. Pre-Creation Tracer Configuration
Available pre-creation scripts See: https://github.com/ethereum/go/ethereum/tree/master/eth/tracers/js/internal/tracers
Input :
curl -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "debug_traceTransaction", "params":[" 0x585218efd4f452912f00878703984c58d2361e89618c9dd57586415756b6476f", {"tracer" : "unigramTracer"}], "id":1}' localhost:8545
Output:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"ADD": 3,
"CALLDATALOAD": 2,
"CALLDATASIZE": 2,
"CALLVALUE": 1,
"DUP1": 7,
"DUP2": 9,
"DUP3": 9,
"DUP4": 1,
"DUP5": 2,
"DUP6": 1,
"EQ": 4,
"GT": 1,
"ISZERO": 3,
"JUMP": 16,
"JUMPDEST": 21,
"JUMPI": 8,
"LT": 1,
"MSTORE": 1,
"POP": 24,
"PUSH1": 15,
"PUSH2": 24,
"PUSH32": 1,
"PUSH4": 3,
"SHR": 1,
"SLOAD": 1,
"SLT": 1,
"SSTORE": 1,
"STOP": 1,
"SUB": 3,
"SWAP1": 12,
"SWAP2": 10,
"SWAP3": 5
}
}
3.2.2.2.3. Custom JavaScript-based Tracer Configuration
See https://geth.ethereum.org/docs/rpc/ns-debug#debug_tracetransaction for syntax
Input :
curl -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "debug_traceTransaction", "params":[" 0x7E031D46C425A78F802E55058733699A341FF44E6778EEEFADD7BBD98F2A0DD6", {"tracer" : "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"SSTORE\") this.data.push(log.stack); }, result: function() { return this.data; }}"}], "id":1}' localhost:8545
Output:
{
"jsonrpc": "2.0",
"id": 1,
"result": [
"0",
"128",
"0",
"0",
"43576122634770472758325941782982599838796957244005075818703754470792663924736",
"154",
"4",
"0",
"0",
"4",
"1",
"1",
"0",
"0",
"1"
]
}
3.2.2.3. Error messages
1. tx (585218EFD4F452912F00878703984C58D2361E89618C9DD57586415756B6476E) not found
Explanation: The specified tx could not be found
- Check if the specified tx has been executed correctly (cannot debug in mempool either)
- Check if the node is an archived node (pruning=nothing)
- Check if the node is started with a non-s3 snapshot, and if the tx height is included in the snapshot.
2. tracer err : ReferenceError: identifier 'unig1ramTracer' undefined
Explanation: The pre-created tracer unig1ramTracer does not exist
- See the support script at:https://github.com/ethereum/go-ethereum/tree/master/eth/tracers/js/internal/tracers
3. tracer err : SyntaxError: parse error (line 1)
Description: Syntax error in the tracer script.
3.2.2.4. Configuration restrictions
debug_traceTransaction(hash common.Hash, config. *vm.Config) takes in config. *vm.Config and if the tracer field is configured, then JavaScript-based tracer is created first and Disable configuration is ignored.