eth-etl-core 0.1.0

Core types and utilities for Ethereum ETL
Documentation
use serde::{Deserialize, Serialize};

/// Smart contract with bytecode and metadata
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct EthContract {
    #[serde(rename = "type", default = "default_contract_type")]
    pub item_type: String,
    pub address: String,
    pub bytecode: String,
    /// Extracted function selectors (4-byte signatures)
    pub function_sighashes: Vec<String>,
    pub is_erc20: bool,
    pub is_erc721: bool,
    pub block_number: u64,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub block_hash: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub block_timestamp: Option<u64>,
}

fn default_contract_type() -> String {
    "contract".to_string()
}

impl EthContract {
    /// Get CSV headers for contract export
    pub fn csv_headers() -> &'static [&'static str] {
        &[
            "address",
            "bytecode",
            "function_sighashes",
            "is_erc20",
            "is_erc721",
            "block_number",
        ]
    }

    /// Convert to CSV row
    pub fn to_csv_row(&self) -> Vec<String> {
        vec![
            self.address.clone(),
            self.bytecode.clone(),
            self.function_sighashes.join(","),
            self.is_erc20.to_string(),
            self.is_erc721.to_string(),
            self.block_number.to_string(),
        ]
    }
}

/// Known ERC20 function selectors
pub const ERC20_SELECTORS: &[&str] = &[
    "0x06fdde03", // name()
    "0x95d89b41", // symbol()
    "0x313ce567", // decimals()
    "0x18160ddd", // totalSupply()
    "0x70a08231", // balanceOf(address)
    "0xa9059cbb", // transfer(address,uint256)
    "0x23b872dd", // transferFrom(address,address,uint256)
    "0x095ea7b3", // approve(address,uint256)
    "0xdd62ed3e", // allowance(address,address)
];

/// Known ERC721 function selectors
pub const ERC721_SELECTORS: &[&str] = &[
    "0x06fdde03", // name()
    "0x95d89b41", // symbol()
    "0x70a08231", // balanceOf(address)
    "0x6352211e", // ownerOf(uint256)
    "0x42842e0e", // safeTransferFrom(address,address,uint256)
    "0xb88d4fde", // safeTransferFrom(address,address,uint256,bytes)
    "0x23b872dd", // transferFrom(address,address,uint256)
    "0x095ea7b3", // approve(address,uint256)
    "0xa22cb465", // setApprovalForAll(address,bool)
    "0x081812fc", // getApproved(uint256)
    "0xe985e9c5", // isApprovedForAll(address,address)
];