| Crates.io | alloy-deadbeef |
| lib.rs | alloy-deadbeef |
| version | 0.0.7 |
| created_at | 2024-12-11 11:46:33.601913+00 |
| updated_at | 2025-03-07 22:59:32.321007+00 |
| description | Brute-force vanity tx prefixes using Alloy |
| homepage | |
| repository | https://github.com/pawurb/alloy-deadbeef |
| max_upload_size | |
| id | 1480003 |
| size | 165,491 |
This crate allows to generate custom, vanity tx hash prefixes:

It brute-forces the correct hash iterating on gas_limit or value fields until it finds a matching prefix. You can read more about the implementation in this blog post.
cargo add alloy-deadbeef
You can use it as an as an alloy provider filler:
let provider = ProviderBuilder::new()
.filler(DeadbeefFiller::new(
"beef".to_string(),
wallet.clone(),
))
.wallet(wallet)
.on_http(endpoint().parse()?);
All the transactions sent from this provider will land with a 0xbeef prefix. If you combine it with other fillers, it has to be the last one. Otherwise hash calculations will be invalid.
Alternatively, you can generate a tx object that, once submitted will have a matching hash prefix:
let tx = TransactionRequest {
from: Some(account),
to: Some(account.into()),
value: Some(U256::ZERO),
chain_id: Some(chain_id),
nonce: Some(nonce),
max_fee_per_gas: Some(gas_price * 110 / 100),
max_priority_fee_per_gas: Some(GWEI_I),
gas: Some(21000),
..Default::default()
};
let deadbeef = DeadbeefFiller::new("beef".to_string(), wallet.clone())?;
let prefixed_tx = deadbeef.prefixed_tx(tx.clone()).await?;
let provider = ProviderBuilder::new()
.wallet(wallet)
.on_http(endpoint().parse()?);
let _ = provider
.send_transaction(tx)
.await?
.get_receipt()
.await?;
For prefixes up to 4 characters, it's possible to send nonpayable transactions because we're iterating on gas_limit instead of value. See this example for details on how to do it.
Alternatively, you can force a specific iteration mode like this:
let mut deadbeef = DeadbeefFiller::new("beef".to_string(), wallet)?;
deadbeef.set_iteration_mode(IterationMode::Value);
The table shows the worst-case scenario processing times on MBP M2 with 12 CPU cores. Check out the blog post for more details.
| Prefix length | 99% certainty time |
|---|---|
| 1 | 547.58µs |
| 2 | 5.81ms |
| 3 | 123.86ms |
| 4 | 1.82s |
| 5 | 29.62s |
| 6 | ~8 minutes |
| 7 | ~128 minutes |
| 8 | ~34 hours |
| 9 | ~23 days |
I'd appreciate feedback on how hash crunching speed can be improved. There's a benchmark to easily measure changes in performance:
cargo bench