First version of the Ethereum explorer
This commit is contained in:
40
ethereum-explorer/src/lib.rs
Normal file
40
ethereum-explorer/src/lib.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
mod pb;
|
||||
|
||||
#[path = "map_block_meta.rs"]
|
||||
mod block_meta;
|
||||
|
||||
#[path = "map_filter_transaction.rs"]
|
||||
mod filter_transaction;
|
||||
|
||||
#[path = "map_contract_events.rs"]
|
||||
mod contract_events;
|
||||
|
||||
|
||||
use pb::eth::transaction::v1::TransactionOption;
|
||||
use substreams_ethereum::pb::eth::v2::Block;
|
||||
use pb::eth::block_meta::v1::BlockMeta;
|
||||
use crate::pb::eth::event::v1::Events;
|
||||
|
||||
substreams_ethereum::init!();
|
||||
|
||||
#[substreams::handlers::map]
|
||||
pub fn map_filter_transaction(transaction_hash: String, blk: Block) -> Result<TransactionOption, substreams::errors::Error> {
|
||||
let filtered_transaction = filter_transaction::filter_by_transaction_hash(transaction_hash, &blk);
|
||||
|
||||
Ok(filtered_transaction)
|
||||
}
|
||||
|
||||
#[substreams::handlers::map]
|
||||
fn map_contract_events(contract_address: String, blk: Block) -> Result<Events, substreams::errors::Error> {
|
||||
let events: Events = contract_events::map_contract_events(contract_address, &blk);
|
||||
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
#[substreams::handlers::map]
|
||||
fn map_block_meta(blk: Block) -> Result<BlockMeta, substreams::errors::Error> {
|
||||
let block_meta = block_meta::map_block_meta(&blk);
|
||||
|
||||
Ok(block_meta)
|
||||
}
|
||||
|
||||
16
ethereum-explorer/src/map_block_meta.rs
Normal file
16
ethereum-explorer/src/map_block_meta.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use substreams_ethereum::pb::eth::v2::Block;
|
||||
use crate::pb::eth::block_meta::v1::BlockMeta;
|
||||
use substreams::Hex;
|
||||
|
||||
pub fn map_block_meta (blk: &Block) -> BlockMeta {
|
||||
let header = blk.header.as_ref().unwrap();
|
||||
|
||||
let hash_string = Hex(&blk.hash).to_string();
|
||||
let parent_hash_string = Hex(&header.parent_hash).to_string();
|
||||
|
||||
return BlockMeta {
|
||||
number: blk.number,
|
||||
hash: hash_string,
|
||||
parent_hash: parent_hash_string
|
||||
}
|
||||
}
|
||||
60
ethereum-explorer/src/map_contract_events.rs
Normal file
60
ethereum-explorer/src/map_contract_events.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
mod pb;
|
||||
use crate::pb::eth::event::v1::Events;
|
||||
use crate::pb::eth::event::v1::Event;
|
||||
use substreams_ethereum::pb::eth::v2::Block;
|
||||
use substreams::Hex;
|
||||
use substreams_ethereum::pb::eth::v2::Log;
|
||||
use substreams_ethereum::pb::eth::v2::TransactionTrace;
|
||||
|
||||
pub fn map_contract_events(contract_address: String, blk: &Block) -> Events {
|
||||
let mut events: Vec<Event> = Vec::new();
|
||||
|
||||
for tr in &blk.transaction_traces {
|
||||
let to = Hex(&tr.to).to_string();
|
||||
|
||||
if to == contract_address {
|
||||
//substreams::log::info!(hash);
|
||||
|
||||
let transaction_events = &mut get_transaction_events(&tr);
|
||||
events.append(transaction_events);
|
||||
|
||||
substreams::log::info!("//////////////////");
|
||||
}
|
||||
}
|
||||
|
||||
return Events { events }
|
||||
}
|
||||
|
||||
fn get_transaction_events(transaction: &TransactionTrace) -> Vec<Event> {
|
||||
let mut transaction_events: Vec<Event> = Vec::new();
|
||||
|
||||
for log in &transaction.receipt().receipt.logs {
|
||||
let address = Hex(&log.address).to_string();
|
||||
let topics = get_log_topics(&log);
|
||||
|
||||
transaction_events.push(create_event_from(address, topics, &transaction.hash))
|
||||
}
|
||||
|
||||
return transaction_events;
|
||||
}
|
||||
|
||||
fn get_log_topics(log: &Log) -> Vec<String> {
|
||||
let mut topics: Vec<String> = Vec::new();
|
||||
|
||||
for topic in &log.topics {
|
||||
let topic_string = Hex(topic).to_string();
|
||||
topics.push(topic_string)
|
||||
}
|
||||
|
||||
return topics;
|
||||
}
|
||||
|
||||
fn create_event_from(address: String, topics: Vec<String>, hash: &Vec<u8>) -> Event {
|
||||
let hash_as_string = Hex(hash).to_string();
|
||||
|
||||
return Event {
|
||||
address,
|
||||
topics,
|
||||
tx_hash: hash_as_string
|
||||
}
|
||||
}
|
||||
32
ethereum-explorer/src/map_filter_transaction.rs
Normal file
32
ethereum-explorer/src/map_filter_transaction.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
mod pb;
|
||||
use substreams_ethereum::pb::eth::v2::Block;
|
||||
use substreams::Hex;
|
||||
use crate::pb::eth::transaction::v1::TransactionOption;
|
||||
use crate::pb::eth::transaction::v1::Transaction;
|
||||
|
||||
|
||||
pub fn filter_by_transaction_hash(transaction_hash: String, blk: &Block) -> TransactionOption {
|
||||
let transaction_traces = &blk.transaction_traces;
|
||||
|
||||
for transfer in transaction_traces {
|
||||
//let transferValue = transfer;
|
||||
let hash = &transfer.hash;
|
||||
let from = &transfer.from;
|
||||
let to = &transfer.to;
|
||||
|
||||
if Hex(hash).to_string() == transaction_hash {
|
||||
let trans = Transaction { from: Hex(from).to_string(), to: Hex(to).to_string(), hash: Hex(hash).to_string() };
|
||||
return transfer_option_of(Some(trans));
|
||||
}
|
||||
}
|
||||
|
||||
return empty_transfer_option()
|
||||
}
|
||||
|
||||
fn transfer_option_of (transaction: Option<Transaction>) -> TransactionOption {
|
||||
return TransactionOption { transaction }
|
||||
}
|
||||
|
||||
fn empty_transfer_option() -> TransactionOption {
|
||||
return transfer_option_of(None)
|
||||
}
|
||||
12
ethereum-explorer/src/pb/eth.block_meta.v1.rs
Normal file
12
ethereum-explorer/src/pb/eth.block_meta.v1.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct BlockMeta {
|
||||
#[prost(uint64, tag="1")]
|
||||
pub number: u64,
|
||||
#[prost(string, tag="2")]
|
||||
pub hash: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="3")]
|
||||
pub parent_hash: ::prost::alloc::string::String,
|
||||
}
|
||||
// @@protoc_insertion_point(module)
|
||||
18
ethereum-explorer/src/pb/eth.event.v1.rs
Normal file
18
ethereum-explorer/src/pb/eth.event.v1.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
// @generated
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Events {
|
||||
#[prost(message, repeated, tag="1")]
|
||||
pub events: ::prost::alloc::vec::Vec<Event>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Event {
|
||||
#[prost(string, tag="1")]
|
||||
pub address: ::prost::alloc::string::String,
|
||||
#[prost(string, repeated, tag="2")]
|
||||
pub topics: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
||||
#[prost(string, tag="3")]
|
||||
pub tx_hash: ::prost::alloc::string::String,
|
||||
}
|
||||
// @@protoc_insertion_point(module)
|
||||
18
ethereum-explorer/src/pb/eth.transaction.v1.rs
Normal file
18
ethereum-explorer/src/pb/eth.transaction.v1.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
// @generated
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct TransactionOption {
|
||||
#[prost(message, optional, tag="1")]
|
||||
pub transaction: ::core::option::Option<Transaction>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Transaction {
|
||||
#[prost(string, tag="1")]
|
||||
pub from: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="2")]
|
||||
pub to: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="3")]
|
||||
pub hash: ::prost::alloc::string::String,
|
||||
}
|
||||
// @@protoc_insertion_point(module)
|
||||
24
ethereum-explorer/src/pb/mod.rs
Normal file
24
ethereum-explorer/src/pb/mod.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
// @generated
|
||||
pub mod eth {
|
||||
pub mod block_meta {
|
||||
// @@protoc_insertion_point(attribute:eth.block_meta.v1)
|
||||
pub mod v1 {
|
||||
include!("eth.block_meta.v1.rs");
|
||||
// @@protoc_insertion_point(eth.block_meta.v1)
|
||||
}
|
||||
}
|
||||
pub mod event {
|
||||
// @@protoc_insertion_point(attribute:eth.event.v1)
|
||||
pub mod v1 {
|
||||
include!("eth.event.v1.rs");
|
||||
// @@protoc_insertion_point(eth.event.v1)
|
||||
}
|
||||
}
|
||||
pub mod transaction {
|
||||
// @@protoc_insertion_point(attribute:eth.transaction.v1)
|
||||
pub mod v1 {
|
||||
include!("eth.transaction.v1.rs");
|
||||
// @@protoc_insertion_point(eth.transaction.v1)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user