RUST ethers 针对不支持EIP-1559交易类型的网络发起合约调用
use std::sync::Arc;
use ethers::{
contract::abigen, middleware::SignerMiddleware, providers::{Http, Middleware, Provider}, signers::{Signer, Wallet}, types::{Address, U256, U64}, utils::hex
};
use eyre::{eyre, Result};
use tracing::{error, info};
pub async fn update_price(&self, provider: Provider<Http>, price: U256) -> Result<()> {
if price.is_zero() {
return Err(eyre!("price is zero"));
}
let chain_id = provider.get_chainid().await.unwrap().as_u64();
let prikey = hex::decode(&self.key).unwrap();
let wallet = Wallet::from_bytes(&prikey).unwrap().with_chain_id(chain_id);
let gas_price = provider.get_gas_price().await.unwrap();
let signer = Arc::new(SignerMiddleware::new(
provider,
wallet.with_chain_id(chain_id),
));
let contract = WFIBOPriceOracle::new(
self.contract_address,
signer,
);
for attempt in 0..self.max_retry {
let tx = contract.update_price(price).legacy(); // 使用 .legacy() 更改交易类型
let gas = match tx.estimate_gas().await { // 预估gas
Ok(v) => v,
Err(err) => {
error!(
"Failed to estimate_gas (attempt {}/{}, error: {})",
attempt + 1,
self.max_retry,
err
);
continue;
}
};
let tx = tx.gas_price(gas_price).gas(gas); // 基于gas_price的交易
let tx_pending = match tx.send().await {
Ok(v) => v,
Err(err) => {
error!(
"Failed to send transaction (attempt {}/{}, error: {})",
attempt + 1,
self.max_retry,
err
);
continue;
}
};
// 等待交易确认
let receipt = match tx_pending.confirmations(6).log_msg("update_price 等待交易确认, hash").await {
Ok(v) => v,
Err(err) => {
error!(
"Failed to confirm transaction (attempt {}/{}, error: {})",
attempt + 1,
self.max_retry,
err
);
continue;
}
};
if let Some(receipt) = receipt {
if receipt.status == Some(U64::from(1)) {
info!("update_price 成功");
return Ok(());
} else {
error!(
"Failed to confirm transaction (attempt {}/{}, error: {})",
attempt + 1,
self.max_retry,
eyre!("receipt.status != 1")
);
}
} else {
error!(
"Failed to confirm transaction (attempt {}/{}, error: {})",
attempt + 1,
self.max_retry,
eyre!("receipt is None")
);
}
}
Err(eyre!(
"Failed to update price after {} attempts",
self.max_retry
))
}