Crates.io | ethereum-mysql |
lib.rs | ethereum-mysql |
version | 3.1.1 |
created_at | 2025-06-07 12:41:33.708067+00 |
updated_at | 2025-09-25 13:30:55.927021+00 |
description | Ethereum types (Address, U256) wrapper for seamless SQL database integration with SQLx |
homepage | |
repository | https://github.com/Rollp0x/ethereum-mysql |
max_upload_size | |
id | 1703966 |
size | 223,945 |
Design Purpose:
ethereum-mysql
is a pragmatic Rust library that provides type-safe, ergonomic wrappers for Ethereum types (Address, U256, FixedBytes, Bytes) for seamless integration with SQLx and relational databases (MySQL, PostgreSQL, SQLite). The crate is designed for real-world Web3/data engineering scenarios, focusing on:
0x...
) in the database, ensuring maximum compatibility and easy inspection.alloy::primitives
types (Address
, U256
, FixedBytes
, Bytes
)SqlAddress
, SqlU256
, SqlFixedBytes
, SqlBytes
for direct DB integrationSqlU256
(U256), including with Rust primitivessqladdress!
, sqlhash!
SqlAddress::ZERO
, SqlU256::ZERO
, SqlU256::ETHER
parse_sether
/format_sether
sqlx_core::Type
, sqlx_core::Encode
, and sqlx_core::Decode
for all wrappersSqlHash
and SqlTopicHash
are exported as type aliases for SqlFixedBytes<32>
All types are stored as strings (hex with 0x
prefix) for maximum compatibility:
Type | Recommended Column Type |
---|---|
SqlAddress | VARCHAR(42) |
SqlU256 | VARCHAR(66) |
SqlFixedBytes |
VARCHAR(2+2*N) |
SqlBytes | TEXT |
TEXT
for all string types.VARCHAR
as above.0x
prefix (e.g. 0x1234...
).0x
-prefixed hex and decimal strings (but hex is recommended for consistency).All wrappers provide compile-time and runtime validation. No more manual string parsing or error-prone conversions in your business logic.
Directly bind and retrieve types from SQLx queries—no intermediate conversions or manual parsing required.
Direct arithmetic and comparison between SqlU256
and Rust primitives, e.g. balance * 25 / 10000
.
Request structs can use SqlAddress
/SqlU256
directly for automatic validation and type safety in web APIs.
Add to your Cargo.toml
:
ethereum-mysql = "3.1.1"
use ethereum_mysql::{SqlAddress, sqladdress};
use std::str::FromStr;
let zero = SqlAddress::ZERO;
let addr = sqladdress!("0x742d35Cc6635C0532925a3b8D42cC72b5c2A9A1d");
let addr2 = SqlAddress::from_str("0x742d35Cc6635C0532925a3b8D42cC72b5c2A9A1d").unwrap();
const ADMIN: SqlAddress = sqladdress!("0x742d35Cc6635C0532925a3b8D42cC72b5c2A9A1d");
use ethereum_mysql::{SqlU256, utils::{parse_sether, format_sether}};
use std::str::FromStr;
// Basic usage
let small = SqlU256::from(42u64);
let large = SqlU256::from(u128::MAX);
let zero = SqlU256::ZERO;
let from_decimal = SqlU256::from_str("123456789").unwrap();
let from_hex = SqlU256::from_str("0x75bcd15").unwrap();
assert_eq!(from_decimal, from_hex);
// Ethereum amount calculations
let one_ether = SqlU256::ETHER; // 10^18 wei
let half_ether = SqlU256::ETHER / 2;
let gas_price = SqlU256::from(20_000_000_000u64); // 20 gwei
// Decimal string parsing and formatting
let amount = parse_sether("1.5").unwrap(); // Parse 1.5 ETH
assert_eq!(format_sether(amount).unwrap(), "1.500000000000000000");
// Arithmetic operations
let a = SqlU256::from(100u64);
let b = SqlU256::from(50u64);
let sum = a + b;
let product = a * b;
let doubled = a * 2;
let tripled = 3 * a;
use ethereum_mysql::{sqlhash, SqlFixedBytes};
// Create various sized hashes at compile time
const TX_HASH: SqlFixedBytes<32> = sqlhash!(32, "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef");
const FUNCTION_SELECTOR: SqlFixedBytes<4> = sqlhash!(4, "0xa9059cbb");
const TOPIC: SqlFixedBytes<32> = sqlhash!(32, "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");
use ethereum_mysql::{SqlAddress, SqlU256, SqlHash};
use sqlx::MySqlPool;
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let pool = MySqlPool::connect("mysql://user:pass@localhost/db").await?;
let user_address = SqlAddress::from_str("0x742d35Cc6635C0532925a3b8D42cC72b5c2A9A1d").unwrap();
let balance = SqlU256::from_str("1000000000000000000").unwrap();
let tx_hash = SqlHash::from_str("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").unwrap();
sqlx::query(
"CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
wallet_address VARCHAR(42) NOT NULL,
balance VARCHAR(66),
tx_hash VARCHAR(66),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)",
)
.execute(&pool)
.await?;
sqlx::query("INSERT INTO users (wallet_address, balance, tx_hash) VALUES (?, ?, ?)")
.bind(&user_address)
.bind(&balance)
.bind(&tx_hash)
.execute(&pool)
.await?;
Ok(())
}
use ethereum_mysql::{SqlAddress, SqlU256, sqladdress};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct User {
id: u64,
wallet: SqlAddress,
balance: SqlU256,
staked_amount: Option<SqlU256>,
}
let user = User {
id: 1,
wallet: sqladdress!("0x742d35Cc6635C0532925a3b8D42cC72b5c2A9A1d"),
balance: SqlU256::from_str("1500000000000000000").unwrap(),
staked_amount: Some(SqlU256::from_str("1000000000000000000").unwrap()),
};
let json = serde_json::to_string(&user)?;
Licensed under either of:
at your option.
Contributions are welcome! Please feel free to submit a Pull Request.