如何提取完整H256哈希值并转为字符串?
问题描述
我正尝试从函数输出中提取哈希值,编写了如下Rust代码:
let receipt = do_something(); println!("{receipt:?}"); let receipt_txn_hash = receipt.transaction_hash; println!("receipt_txn_hash: {}", receipt_txn_hash); let tx = provider.get_transaction(receipt_txn_hash).await?; println!("tx: {}\n", serde_json::to_string(&tx)?); let tx_hash = if let Some(txn) = tx { txn.hash.to_string() } else { "hash_not_found".to_owned() //H256([0; 32]) }; println!("tx.hash: {}\n", &tx_hash);
终端输出如下:
TransactionReceipt { transaction_hash: 0xd6a0e48e6a0f80ae4467193f40721da1ad53ec854a738ea57d7201619e60f3b7, ... } receipt_txn_hash: 0xd6a0…f3b7 tx: {"hash":"0xd6a0e48e6a0f80ae4467193f40721da1ad53ec854a738ea57d7201619e60f3b7",...} tx.hash: 0xd6a0…f3b7
Rust-Analyzer识别receipt为{unknown}类型,tx为Option<Transaction>类型。但receipt.transaction_hash与tx.hash均被截断。经确认,二者均为H256类型,其Display trait默认实现会截断哈希。由于Rust孤儿规则,无法修改外部依赖的trait实现,现需自定义本地类型NewH256实现完整的fmt::Display,以获取完整哈希字符串,该如何操作?
依赖如下:
ethers = { version = "1.0.2", features = ["legacy", "rustls"] } ethers-solc = { version = "1.0.2", features = ["full"] } ethers-providers = "1.0.2" eyre = "0.6.8" hex = "0.4.3" reqwest = { version = "0.11.14", default-features = false } serde_json = "1.0.93"
解决方案
1. 定义包装类型NewH256
通过**新类型模式(Newtype Pattern)**包装H256,绕开孤儿规则实现自定义Display:
use ethers::types::H256; use std::fmt; #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct NewH256(H256); // 实现完整的Display格式 impl fmt::Display for NewH256 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // 调用H256的Debug实现输出完整哈希,或手动格式化十六进制字符串 write!(f, "{:#x}", self.0) // 也可以用hex库手动转换: // write!(f, "0x{}", hex::encode(self.0.as_bytes())) } } // 实现从H256到NewH256的转换,方便直接包装 impl From<H256> for NewH256 { fn from(value: H256) -> Self { NewH256(value) } }
2. 在代码中使用NewH256
将原有的H256类型转换为NewH256后再输出:
// 处理receipt的哈希 let receipt_txn_hash = receipt.transaction_hash; // 转换为NewH256后输出完整哈希 println!("receipt_txn_hash: {}", NewH256::from(receipt_txn_hash)); // 处理tx的哈希 let tx_hash = if let Some(txn) = tx { NewH256::from(txn.hash).to_string() } else { "hash_not_found".to_owned() }; println!("tx.hash: {}\n", &tx_hash);
3. 可选:实现Deref简化访问
如果需要频繁访问内部H256的方法,可以实现Deref trait,让NewH256可以直接当作H256使用:
use std::ops::Deref; impl Deref for NewH256 { type Target = H256; fn deref(&self) -> &Self::Target { &self.0 } }
这样你可以直接调用NewH256实例的as_bytes()、is_zero()等方法,无需手动解包。
内容的提问来源于stack exchange,提问作者Russo
相关产品推荐
相关产品推荐

