Packages
signet
1.6.1
1.6.1
1.6.0
1.5.0
1.4.2
1.4.1
1.4.0
1.3.12
1.3.11
1.3.10
1.3.9
1.3.8
1.3.7
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.0-echo8
1.0.0-echo7
1.0.0-echo6
1.0.0-echo5
1.0.0-echo4
1.0.0-echo3
1.0.0-echo2
1.0.0-echo1
1.0.0-delta8
1.0.0-delta7
1.0.0-delta6
1.0.0-delta5
1.0.0-delta4
1.0.0-delta3
1.0.0-delta2
1.0.0-delta1
1.0.0-charlie9
1.0.0-charlie8
1.0.0-charlie7
1.0.0-charlie6
1.0.0-charlie5
1.0.0-charlie4
1.0.0-charlie3
1.0.0-charlie2
1.0.0-charlie1
1.0.0-beta9
1.0.0-beta8
1.0.0-beta7
1.0.0-beta6
1.0.0-beta5
1.0.0-beta4
1.0.0-beta3
1.0.0-beta2
1.0.0-beta1
1.0.0-alpha9
1.0.0-alpha8
1.0.0-alpha7
1.0.0-alpha6
1.0.0-alpha5
1.0.0-alpha4
1.0.0-alpha3
1.0.0-alpha2
1.0.0-alpha10
1.0.0-alpha1
0.2.0-alpha6
0.2.0-alpha5
0.2.0-alpha4
0.2.0-alpha1
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.1.0-rc7
0.1.0-rc6
0.1.0-rc5
0.1.0-rc4
0.1.0-rc3
0.1.0-rc2
0.1.0-rc1
0.1.0-rc0
Lightweight Ethereum and Solana RPC client for Elixir
Current section
Files
Jump to
Current section
Files
lib/signet/debug_trace.ex
defmodule Signet.DebugTrace do
@moduledoc ~S"""
Represents an Ethereum transaction debug trace, which contains information
about the call graph of an executed transaction. Note: this is different
from `trace_call` and instead has deep struct logs for execution.
See `Signet.RPC.debug_trace_call` for getting traces from
an Ethereum JSON-RPC host.
See also:
* QuickNode docs: https://www.quicknode.com/docs/ethereum/debug_traceCall
"""
use Signet.Hex
defmodule StructLog do
@type t() :: %__MODULE__{
depth: integer(),
gas: integer(),
gas_cost: integer(),
op: atom(),
pc: integer(),
stack: [binary()]
}
defstruct [
:depth,
:gas,
:gas_cost,
:op,
:pc,
:stack
]
@doc ~S"""
Deserializes a trace's struct-log into a struct.
## Examples
iex> %{
...> "depth" => 1,
...> "gas" => 599978565,
...> "gasCost" => 3,
...> "op" => "PUSH1",
...> "pc" => 2,
...> "stack" => ["0x80"]
...> }
...> |> Signet.DebugTrace.StructLog.deserialize()
%Signet.DebugTrace.StructLog{
depth: 1,
gas: 599978565,
gas_cost: 3,
op: :PUSH1,
pc: 2,
stack: [~h[0x80]]
}
"""
@spec deserialize(map()) :: t() | no_return()
def deserialize(params) do
%__MODULE__{
depth: params["depth"],
gas: params["gas"],
gas_cost: params["gasCost"],
op: String.to_atom(params["op"]),
pc: params["pc"],
stack: Enum.map(params["stack"], &Signet.Hex.decode_hex!/1)
}
end
@doc ~S"""
Serializes a trace's struct-log into a json map.
## Examples
iex> %Signet.DebugTrace.StructLog{
...> depth: 1,
...> gas: 599978565,
...> gas_cost: 3,
...> op: :PUSH1,
...> pc: 2,
...> stack: [~h[0x80]]
...> }
...> |> Signet.DebugTrace.StructLog.serialize()
%{
depth: 1,
gas: 599978565,
gasCost: 3,
op: "PUSH1",
pc: 2,
stack: ["0x80"]
}
"""
@spec serialize(t()) :: map()
def serialize(struct_log) do
%{
depth: struct_log.depth,
gas: struct_log.gas,
gasCost: struct_log.gas_cost,
op: to_string(struct_log.op),
pc: struct_log.pc,
stack: Enum.map(struct_log.stack, &Signet.Hex.to_hex/1)
}
end
end
@type t() :: %__MODULE__{
failed: boolean(),
gas: integer(),
return_value: binary(),
struct_logs: [StructLog.t()]
}
defstruct [
:failed,
:gas,
:return_value,
:struct_logs
]
@doc ~S"""
Deserializes a trace result from `debug_traceCall`.
## Examples
iex> %{
...> "failed" => false,
...> "gas" => 24034,
...> "returnValue" => "0000000000000000000000000000000000000000000000000858898f93629000",
...> "structLogs" => [
...> %{
...> "depth" => 1,
...> "gas" => 599978568,
...> "gasCost" => 3,
...> "op" => "PUSH1",
...> "pc" => 0,
...> "stack" => []
...> },
...> %{
...> "depth" => 1,
...> "gas" => 599978565,
...> "gasCost" => 3,
...> "op" => "PUSH1",
...> "pc" => 2,
...> "stack" => ["0x80"]
...> },
...> %{
...> "depth" => 1,
...> "gas" => 599978562,
...> "gasCost" => 12,
...> "op" => "MSTORE",
...> "pc" => 4,
...> "stack" => ["0x80", "0x40"]
...> }
...> ]
...> }
...> |> Signet.DebugTrace.deserialize()
%Signet.DebugTrace{
failed: false,
gas: 24034,
return_value: ~h[0x0000000000000000000000000000000000000000000000000858898f93629000],
struct_logs: [
%Signet.DebugTrace.StructLog{
depth: 1,
gas: 599978568,
gas_cost: 3,
op: :PUSH1,
pc: 0,
stack: []
},
%Signet.DebugTrace.StructLog{
depth: 1,
gas: 599978565,
gas_cost: 3,
op: :PUSH1,
pc: 2,
stack: [~h[0x80]]
},
%Signet.DebugTrace.StructLog{
depth: 1,
gas: 599978562,
gas_cost: 12,
op: :MSTORE,
pc: 4,
stack: [~h[0x80], ~h[0x40]]
}
]
}
"""
@spec deserialize(map()) :: t() | no_return()
def deserialize(params) do
%__MODULE__{
failed: params["failed"],
gas: params["gas"],
return_value: Signet.Hex.decode_hex!(params["returnValue"]),
struct_logs: Enum.map(params["structLogs"], &StructLog.deserialize/1)
}
end
@doc ~S"""
Serializes a trace result back to a json map.
## Examples
iex> %Signet.DebugTrace{
...> failed: false,
...> gas: 24034,
...> return_value: ~h[0x0000000000000000000000000000000000000000000000000858898f93629000],
...> struct_logs: [
...> %Signet.DebugTrace.StructLog{
...> depth: 1,
...> gas: 599978568,
...> gas_cost: 3,
...> op: :PUSH1,
...> pc: 0,
...> stack: []
...> },
...> %Signet.DebugTrace.StructLog{
...> depth: 1,
...> gas: 599978565,
...> gas_cost: 3,
...> op: :PUSH1,
...> pc: 2,
...> stack: [~h[0x80]]
...> },
...> %Signet.DebugTrace.StructLog{
...> depth: 1,
...> gas: 599978562,
...> gas_cost: 12,
...> op: :MSTORE,
...> pc: 4,
...> stack: [~h[0x80], ~h[0x40]]
...> }
...> ]
...> }
...> |> Signet.DebugTrace.serialize()
%{
failed: false,
gas: 24034,
returnValue: "0000000000000000000000000000000000000000000000000858898f93629000",
structLogs: [
%{
depth: 1,
gas: 599978568,
gasCost: 3,
op: "PUSH1",
pc: 0,
stack: []
},
%{
depth: 1,
gas: 599978565,
gasCost: 3,
op: "PUSH1",
pc: 2,
stack: ["0x80"]
},
%{
depth: 1,
gas: 599978562,
gasCost: 12,
op: "MSTORE",
pc: 4,
stack: ["0x80", "0x40"]
}
]
}
"""
@spec serialize(t()) :: map()
def serialize(debug_trace) do
%{
failed: debug_trace.failed,
gas: debug_trace.gas,
returnValue: String.replace_prefix(to_hex(debug_trace.return_value), "0x", ""),
structLogs: Enum.map(debug_trace.struct_logs, &StructLog.serialize/1)
}
end
end