moonbeam_client_evm_tracing/formatters/
blockscout.rs

1// Copyright 2019-2025 PureStake Inc.
2// This file is part of Moonbeam.
3
4// Moonbeam is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Moonbeam is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16
17use crate::listeners::call_list::Listener;
18use crate::types::serialization::*;
19use crate::types::{
20	single::{Call, TransactionTrace},
21	CallResult, CallType, CreateResult,
22};
23use ethereum_types::{H160, U256};
24use parity_scale_codec::{Decode, Encode};
25use serde::Serialize;
26
27pub struct Formatter;
28
29impl super::ResponseFormatter for Formatter {
30	type Listener = Listener;
31	type Response = TransactionTrace;
32
33	fn format(listener: Listener) -> Option<TransactionTrace> {
34		if let Some(entry) = listener.entries.last() {
35			return Some(TransactionTrace::CallList(
36				entry
37					.into_iter()
38					.map(|(_, value)| Call::Blockscout(value.clone()))
39					.collect(),
40			));
41		}
42		None
43	}
44}
45
46#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, Serialize)]
47#[serde(rename_all = "lowercase", tag = "type")]
48pub enum BlockscoutCallInner {
49	Call {
50		#[serde(rename(serialize = "callType"))]
51		/// Type of call.
52		call_type: CallType,
53		to: H160,
54		#[serde(serialize_with = "bytes_0x_serialize")]
55		input: Vec<u8>,
56		/// "output" or "error" field
57		#[serde(flatten)]
58		res: CallResult,
59	},
60	Create {
61		#[serde(serialize_with = "bytes_0x_serialize")]
62		init: Vec<u8>,
63		#[serde(flatten)]
64		res: CreateResult,
65	},
66	SelfDestruct {
67		#[serde(skip)]
68		balance: U256,
69		to: H160,
70	},
71}
72
73#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, Serialize)]
74#[serde(rename_all = "camelCase")]
75pub struct BlockscoutCall {
76	pub from: H160,
77	/// Indices of parent calls.
78	pub trace_address: Vec<u32>,
79	/// Number of children calls.
80	/// Not needed for Blockscout, but needed for `crate::block`
81	/// types that are build from this type.
82	#[serde(skip)]
83	pub subtraces: u32,
84	/// Sends funds to the (payable) function
85	pub value: U256,
86	/// Remaining gas in the runtime.
87	pub gas: U256,
88	/// Gas used by this context.
89	pub gas_used: U256,
90	#[serde(flatten)]
91	pub inner: BlockscoutCallInner,
92	pub logs: Vec<crate::types::single::Log>,
93}