You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取完整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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:25:22