以太坊在没有收据的情况下检索交易状态



假设我是Alice,我的任务是通过部署在Avalache子网上的智能合约将N个ERC20令牌从我的地址转移到我的客户端Bob。我想用Rust程序来执行我的智能合约transfer函数。假设我使用ethers-rs,并具有以下代码:

let tx = self.contract.transfer(addr_to, amount).tx;
let _res: TypedTransaction = tx;
if let Some(receipt) = self
.contract
.transfer(addr_to, amount)
.send()
.await
.map_err(|e| EthersTransferError(e.to_string()))?
.await
.map_err(|e| EthersTransferError(e.to_string()))?
{
return Ok(receipt);
}

此代码完成交易并返回包含交易哈希,状态和其他重要信息的收据大约需要5秒。但问题是:如果我的程序在收到收据之前的5秒内崩溃了怎么办?所以我的交易可能成功,也可能不成功,我无法检查,因为除了from address,to address,amountsmart-contract address,我没有收据和其他任何信息。但是我需要知道我的交易是否成功,我应该转移令牌exactly once。那么在这种情况下我能做什么呢?我的想法是从最后的块中获取事件,并在其中找到我的事务,所以我这样做:

async fn find_tx(&self, to: Address, amount: U256, from_block: BlockNumber) -> Result<()> {
let filter = Filter::new()
.address(self.contract_addr)
.event("Transfer(address,address,uint256)")
.topic2(H256::from(to))
.from_block(from_block);
let mut interval = time::interval(time::Duration::from_secs(600));
loop {
interval.tick().await;
let logs = self
.client
.get_logs(&filter)
.await
.map_err(|e| AvalancheGetLogsError(e.to_string()))?;
for log in logs.iter() {
if self.client.address() == Address::from(log.topics[1])
&& to == Address::from(log.topics[2])
&& amount == U256::from(log.data.as_bytes_ref())
{
return Ok(());
}
}
}
}

这个解决方案的问题是a)一些链设置了要过滤的最大区块数量(如Fuji testnet - 2048个区块),而我的交易可能远远超过了这个限制,b)它可以检查交易是否失败,代码将在无限循环中堆叠,我将不得不等待几天来确保交易没有到达。

所以,我需要用有限的信息找到我的交易状态。你认为最好的方案是什么?我相信我不是第一个遇到这个问题的人。我必须依赖承载我的子网的服务的API吗?索引器,浏览器?以某种方式扩展智能合约功能以进行额外检查?Geth是否有足够的功能来解决这个问题?我有点迷糊了。提前感谢

  • 将事务哈希值存储到数据库

  • 您可以使用eth_getTransactionReceipt

    通过交易哈希查询交易收据,状态和日志
  • 如果您的节点没有存储旧收据,或者正在修剪

    • 自己运行节点

    • 切换到更高质量的付费节点提供商

最新更新