[Feature] Getting tx hash before sending is too hard
- 主要語言
- Rust
- 星號
- 1.3k
- 分支
- 668
- 平均合併
- 2 天 2 小時
- 30 天內合併 PR
- 29
描述
### Component
provider, pubsub
### Describe the feature you would like
**[Feature] Getting tx hash before sending is too hard**
I need a way to get tx hash before sending. Currently this is too hard. (In the end of this issue I will describe why I need this.)
Let's assume we want to send tx to contract on Sepolia. Using `PrivateKeySigner`, with default fillers. This is how I can do this:
```rust
// alloy 0.15.9
// alloy-core 1.1.0
// https://sepolia.etherscan.io/address/0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14
alloy::sol!(
#[sol(rpc)]
interface IWETH9 {
function deposit() public payable;
}
);
use alloy::signers::local::PrivateKeySigner;
use alloy::primitives::b256;
use alloy::providers::ProviderBuilder;
use alloy::primitives::address;
use alloy::primitives::U256;
#[tokio::main]
async fn main() {
// https://sepolia.etherscan.io/address/0x1D56416a0b4B0ac6eB07bA47ecc881de056d6Efb
let signer = PrivateKeySigner::from_bytes(&b256!("0xa110aaaaaaaaaaaaaaa110aaaaaaaaaaaaaaaaaaaaaaa110aaaaaaaaaaaa110a")).unwrap();
let provider = ProviderBuilder::new().wallet(signer).connect_http("https://rpc.sepolia.ethpandaops.io".parse().unwrap());
let weth9 = IWETH9::new(address!("0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"), provider);
println!("{}", weth9.deposit().value(U256::from(1)).send().await.unwrap().watch().await.unwrap());
}
```
So far, so good. Now let's assume we want to do the same thing, but we want to get tx hash before sending tx. With default fillers, of course, I don't want to manually fill nonce, etc.
I was unable to find such use case in docs. There is no info in alloy book or in examples. I even thought that this is not possible. After a lot of tries I was able to come up with this:
```rust
// alloy 0.15.9
// alloy-core 1.1.0
// https://sepolia.etherscan.io/address/0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14
alloy::sol!(
#[sol(rpc)]
interface IWETH9 {
function deposit() public payable;
}
);
use alloy::providers::Provider;
use alloy::signers::local::PrivateKeySigner;
use alloy::primitives::b256;
use alloy::providers::ProviderBuilder;
use alloy::primitives::address;
use alloy::primitives::U256;
use alloy::providers::SendableTx;
#[tokio::main]
async fn main() {
// https://sepolia.etherscan.io/address/0x1D56416a0b4B0ac6eB07bA47ecc881de056d6Efb
let signer = PrivateKeySigner::from_bytes(&b256!("0xa110aaaaaaaaaaaaaaa110aaaaaaaaaaaaaaaaaaaaaaa110aaaaaaaaaaaa110a")).unwrap();
let provider = ProviderBuilder::new().wallet(signer).connect_http("https://rpc.sepolia.ethpandaops.io".parse().unwrap());
let weth9 = IWETH9::new(address!("0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"), provider.clone());
let SendableTx::Envelope(envelope) = provider.fill(weth9.deposit().value(U256::from(1)).into_transaction_request()).await.unwrap() else {
unreachable!();
};
println!("{}", envelope.hash());
println!("{}", provider.send_tx_envelope(envelope).await.unwrap().watch().await.unwrap());
}
```
If there is a simpler way to do this, please, let me know.
So, please, make this use case simpler.
If you think that current API is okay, then, at least, include this example to docs.
Now let me explain why I need this.
I want to write trading bot. The bot will write every its operation to my accounting system. I want the following rule to always hold: "Operation should be in accounting if and only if it was actually executed on chain". The rule should be true even in presence of crashes, panics, etc.
Unfortunately, I was unable to create scheme, which will allow me to enforce this rule fully automatically. So I created scheme, which will enforce the rule mostly automatically with occasional manual intervention.
My scheme is so: when my bot needs to perform some operation (i. e. Ethereum transaction), it does these steps:
- The bot writes transaction hash to log
- The bot sends transaction and waits for confirmations
- The bot writes operation to accounting
If bot crashes, then I intervene manually. I look into logs. I find last transaction present in logs. I see whether it was executed on-chain and whether it is present in accounting. If it was executed, but is not present in accounting, then I manually add it to accounting.
Okay, so this system works.
But this system requires me to know tx hash before sending transaction! And this is why I need this.
### Additional context
_No response_
貢獻指南
評估
這個 Issue 還沒有評估資料。