Cointime

Download App
iOS & Android

Releasing Alloy

From paradigm by Georgios Konstantopoulos, James Prestwich, Matthias Seitz, DaniPopes, Yash Atreya, Zerosnacks, Enrique Ortiz

Contents

The story so far

One year ago, we announced Alloy, our full rewrite of the low-level building blocks for interacting with EVM blockchains, from the RPC types, down to the ABI encoders and primitive types.

Today, we’re releasing Alloy 0.1 (crates), the first release of the Alloy project including all the necessary utilities for interacting with an EVM-based blockchain. This release includes multiple API improvements and new features which we are excited to finally share with our users. As part of this release, we’re also officially stopping maintenance of ethers-rs, and we’re encouraging everyone to move to Alloy.

While we are only now releasing Alloy as the top-level package including all JSON-RPC functionality, the packages inside of Alloy Core with low-level type & ABI coders have been released for a few months now, and many of them have >1 million all time downloads already!

To help users get up to speed with Alloy, we’re publishing the Alloy Book (including an ethers to alloy migration guide), the Alloy and Alloy Core docs, as well as a lot of examples showing all sorts of ways you can consume Alloy.

Alloy is already integrated in many Rust codebases, as well as all the projects we’re working on: RevmFoundry and Reth. We’ve been using it in production ourselves for months, and we’re excited for it to be a performant and stable foundation for the Rust Ethereum ecosystem, as we envisioned in our original announcement.

With that out of the way, let’s dive in!

What are the highlights of the Alloy release?

Alloy is written from the bottom-up to be performant, safe to use, and intuitive. We took our learnings from 4 years of ethers-rs development and put them all into designing a great client-side library for interacting with EVM-based blockchains.

This took a lot of time, 1 year since we announced the Alloy project, but we’re proud of the result.

Today we are excited to reveal some exciting new features co-architected and co-developed by our core team alongside James Prestwich who’s been maintaining Alloy with the rest of us over the last year. Big shoutout & thank you to James for pushing us to go beyond what ethers-rs allowed us before, and for being a core input to the successful delivery of today’s release.

Reworked Provider Middleware architecture

The most important abstraction in a RPC client library is the Provider, which lets you interact with the network. Users commonly want to extend basic provider operations: different gas estimations, gas escalators, alternative signing pipelines, and more. You want to do this in a modular way which empowers the developer to extend the behavior of the core library, instead of having to modify it.

In ethers-rs, we had defined the Middleware as the one-stop shop for modifying your RPC client’s behavior. If you wanted nonce management, it’s a middleware. Gas escalation, it’s a middleware. Signing transactions? Middleware. Flashbots bundles? Middleware. This approach worked because it gave us a lot of flexibility to override things as we wanted, but it also was too error prone, and had poor developer experience (e.g. expecting devs to panic when a function that’s required by the Middleware trait does not make sense to implement).

Alloy redesigned that abstraction from the ground up. We split the Middleware in 3 overridable abstractions:

  • Transport Layers: The Transport is the “wire” that carries over your data to the node. This now implement’s Tower’s Service Layers which allows tapping into the Tower Ecosystem for common middleware such as request retries, rate limits and more.
  • Provider Layers: Modeled after Tower’s Layers this allows overriding various Provider functionalities, e.g. if you wanted to hijack the get_storage_at method, you’d implement a ProviderLayer.
  • Fillers: This is probably the most exciting abstraction, Fillers handle everything about the transaction’s lifecycle. A user generally submits a partially populated transaction, and the provider is responsible for figuring out what data is missing and filling it in. Fillers can be installed independent of order from each other, solving a major footgun from ethers-rs. We provide the .with_recommended_fillers() method which aggregates commonly used Fillers via multiple JoinFill ProviderLayers for convenience:Wallet Filler: Signs a transaction with a credential from a wide suite: a local private key parsed from a hex string, a 12/24-word mnemonic, a keystore file, a hardware wallet like Trezor or Ledger, or even from a productionized key management system such as YubiHSM, AWS KMS or GCP KMS.Nonce Filler: Automatically manages nonces across all accounts.Gas Filler: Handles calculating the gas price and the gas limit for each transaction.ChainId Filler: Embeds the correct chain ID into transactions depending on which chain is connected.
  • Wallet Filler: Signs a transaction with a credential from a wide suite: a local private key parsed from a hex string, a 12/24-word mnemonic, a keystore file, a hardware wallet like Trezor or Ledger, or even from a productionized key management system such as YubiHSM, AWS KMS or GCP KMS.
  • Nonce Filler: Automatically manages nonces across all accounts.
  • Gas Filler: Handles calculating the gas price and the gas limit for each transaction.
  • ChainId Filler: Embeds the correct chain ID into transactions depending on which chain is connected.

Putting it all together, the stack of features we have can be seen below:

This stack is bundled and exposed to the user via the ProviderBuilder which has a very ergonomic API:

// Create a signer from a random private key. let signer = PrivateKeySigner::random(); let provider = ProviderBuilder::new() // configures all the fillers .with_recommended_fillers() // sets the signer, allows configuring more than 1 signer which will be picked based on your transaction's `from` field. .wallet(EthereumWallet::from(signer)) // connects to the chain // can also use `.on_http`, `.on_ws`, or `.on_ipc` for no dyn dispatch // can also use `.on_anvil` for local testing // can also use `.on_client` for configuring auth options e.g. bearer auth. .on_builtin("ws://localhost:8545") .await?; let tx = TransactionRequest::new().with_to(...).with_value(...); let receipt = provider.send_transaction(tx).await?.get_receipt().await?; // do something with the receipt

Oh, we also made sure the Provider and Signers are object-safe, to make it easier to avoid generics in your code by Boxing them. For more on how to consume providers, see the book.

RPC Types Abstraction

The world is going multichain, and that means more differences in RPC types! That was one of the most painful things in ethers-rs where we supported e.g. Celo-related fields with a feature flag. This meant that if you wanted to have a type-safe connection to both Celo and Ethereum you had to choose between importing the library twice, or expecting that the Celo fields would be None in all cases in Ethereum. This is a problem that we set out to fix.

In Alloy, we define the Network trait which defines the “shape” of every network for all its RPC requests and responses where each type must implement certain traits, e.g. Eip2718EnvelopeTxReceiptTransactionBuilder, summarized below:

pub trait Network { /// The network transaction type enum. type TxType /// The network transaction envelope type. type TxEnvelope: Eip2718Envelope + Debug; /// An enum over the various transaction types. type UnsignedTx: From<Self::TxEnvelope>; /// The network receipt envelope type. type ReceiptEnvelope: Eip2718Envelope + TxReceipt; /// The network header type. type Header; /// The JSON body of a transaction request. type TransactionRequest: RpcObject + TransactionBuilder<Self> + Debug + From<Self::TxEnvelope> + From<Self::UnsignedTx>; /// The JSON body of a transaction response. type TransactionResponse: RpcObject + TransactionResponse; /// The JSON body of a transaction receipt. type ReceiptResponse: RpcObject + ReceiptResponse; /// The JSON body of a header response. type HeaderResponse: RpcObject; }

This allows us to import the library once without any feature flags, and depending on what network we specify we get different type abstractions. This is great! Type-safety, without redundant overhead! This is also the approach we’re taking in Reth for allowing any developer to build a chain with custom RPC types on the server side, such as a network with native account abstraction.

We provide two network implementations Ethereum and AnyNetwork. Ethereum contains all the types you know and love. AnyNetwork however, wraps every RPC type with the WithOtherFields<T> type which acts as a catch-all for any RPC response fields that do not match the Ethereum structure.

A developer can choose their Network implementation using the .network::() method on the ProviderBuilder. This allows us to support more networks than just Ethereum in a principled way, without burdening the core maintenance process. All you need to do is implement the network trait and all its associated types, import it in your code, and you’re done!

Follow our work on defining the OpStackNetwork in the op-alloy crate, and reach out if you want to implement your own network!

The sol! Macro

We first talked about the sol macro in our initial post. It is a rework of our previous abigen macro, which was used to generate type-safe bindings to a contract’s ABI. The sol macro is not a compiler, but it is a complete representation of the Solidity type system in Rust, which means you can just paste Solidity in it, and it’ll codegen bindings for it, even allowing support for custom types!

The sol macro also codegens JSON RPC bindings via the #[sol(rpc)] attribute. A deployer method is also generated if you pass it the #[sol(bytecode = "...")] attribute. For example, the code below would generate a Counter::deploy function as well as a Counter::increment(&self) method which you can use to increment the counter.

sol! { // solc v0.8.26; solc a.sol --via-ir --optimize --bin #[sol(rpc, bytecode="608080...")] contract Counter { uint256 public number; function increment() public { number++; } } }

To learn more about the sol macro, check the page on the book and its detailed documentation. Interacting with a smart contract is similar to ethers-rs (note, no more Arcs!), with minor underlying changes in the API for fetching a transaction’s receipt.

let provider = ProviderBuilder::new().on_builtin("...").await?; // Deploy the contract. let contract = Counter::deploy(&provider).await?; println!("Deployed contract at address: {}", contract.address()); let receipt = contract.setNumber(U256::from(42)).send().await?.get_receipt().await?; println!("Receipt: {receipt}"); // Increment the number to 43 (without waiting for the receipt) let tx_hash = contract.increment().send().await?.watch().await?; println!("Incremented number: {tx_hash}"); // Retrieve the number, which should be 43. let number = contract.number().await?.number.to_string(); println!("Retrieved number: {number}");

The sol macro’s functionality is also integrated with Foundry in forge bind for generating type-safe bindings for all your client-side integrations. Check out the updated Foundry Rust template if that’s of interest to you!

Extensive documentation and tests

We want our users to be equipped with high-level tutorials & examples for consuming the project, as a library. To achieve that, we provide a large surface area of documentation:

  • Alloy Docs: Rustdoc documentation for each function on the Alloy repository.
  • Alloy Core Docs: Rustdoc documentation for each function on the Alloy Core repository.
  • Alloy Examples: Wide range of code examples on how to consume Alloy in your day to day.
  • Alloy Book: Tutorials and long form writeups about all things Alloy.

Making the docs excellent is a top priority for us, please open issues on the book with more tutorials you’d like to see.

What is next for Alloy?

Today’s 0.1 release marks Alloy at feature parity with ethers-rs and beyond, while also being performant, well-tested and well-documented. We think Alloy is the tool of choice for power users, yet it is simple and intuitive enough for anyone to work with.

Our next priority is the 1.0 release, which means we’ll be polishing our APIs and working towards proper stability. While we don’t offer any formal stability guarantees, most of the APIs are baked, and we do not expect large changes.

To help achieve Alloy’s long term success, we’re looking to add 1 full-time staff-level engineer to the Alloy team who will help drive the day to day of the project, as well as help us grow the contributor base. If the above sounds interesting, please reach out to [email protected].

We’re excited for every ethers-rs user to port their code to use Alloy, as well as new services to be built with it! Go read the docs of alloy-core and alloy, the examples, and the book!

Until then, see you on Github!

Comments

All Comments

Recommended for you

  • Iranian Official: US Provocation on Strait of Hormuz is a Reactive Response

    According to IRNA, Hussein Nushabadi, the Director General of the Iranian Foreign Ministry's Parliamentary and Legal Affairs Department, stated in an interview that Washington's controversial claims regarding control over the Strait of Hormuz are primarily driven by domestic political needs and are a reactive response to Iran's demonstrated strength and strategic actions in this waterway. He noted that the baseless assertions made by the US President regarding the Strait of Hormuz do not align with international shipping regulations or the relevant provisions of the United Nations Convention on the Law of the Sea. Nushabadi also pointed out that Iran possesses political and military dominance over the Strait of Hormuz, a vital lifeline for global energy and economy, making it a powerful lever and strategic trump card in responding to external threats.

  • Jensen Huang Collaborates with Wall Street Giants to Support AI Computing Market

    On August 15, a rare scene unfolded as Jensen Huang joined forces with six major Wall Street asset management giants to endorse the idea of establishing AI computing as an independent asset class. Analysts believe this reflects Huang's commitment to the concept of token economics, marking a shift in the AI boom from a technological competition to a capital competition. However, the latest plan has raised concerns among investors regarding 'circular financing' and debt risks. In response to these doubts, Huang personally stepped in to reassure the market, stating that Nvidia may provide a residual value support mechanism of up to 25% for individual investment projects and will carefully evaluate each project. Following this, market sentiment showed slight improvement. (CCTV Finance)

  • DJI Added to 'Blacklist', US Court Orders Rehearing

    On August 15, according to the Russian Satellite News Agency, the U.S. Court of Appeals recently ruled that a lower court must rehear the case regarding the inclusion of Chinese drone manufacturer DJI on the Pentagon's 'Chinese Military Industrial Enterprises' blacklist, stating that the previous ruling was based on non-confidential information and contained flaws. The report indicated that the D.C. Circuit Court of Appeals pointed out that the lower court's conclusion that DJI 'contributes to China's defense industrial base' was erroneous, as it relied solely on publicly available information. The court has mandated that during the rehearing, the lower court may review classified documents and decide whether to uphold the Department of Defense's designation based on that information.

  • Iran Claims Undisputed Ownership of Strait of Hormuz

    On August 15, according to CCTV International News, Iran's Chief Justice Ejei stated today that the absurd remarks made by the U.S. President regarding the Strait of Hormuz are entirely based on his personal delusions. In the real world, the true owner and dominant power of this important international waterway is Iran. Ejei emphasized that Iran has proven militarily that the Strait of Hormuz is an inseparable part of Iranian territory and sovereignty.

  • US Spot Bitcoin ETF Sees Net Outflow of $56.2 Million Yesterday

    On August 15, according to data monitored by Farside Investors, the US spot Bitcoin ETF experienced a net outflow of $56.2 million yesterday.

  • No Net Inflow or Outflow for US Spot Ethereum ETF Yesterday

    On August 15, according to monitoring data from Farside Investors, there was no net inflow or outflow for the US spot Ethereum ETF yesterday.

  • Charles Schwab: Low Probability of CLARITY Act Passing Before U.S. Midterm Elections

    On August 15, Charles Schwab stated in its 'Weekly Trader Market Outlook' that as of the time of writing, the Bitwise Top 10 Large Cap Crypto Index has fallen 3% since last Friday; Bitcoin has dropped 3% during the same period, while Ethereum is down 2%. Bitcoin continues to exhibit characteristics of a low-correlation asset, with limited impact on its price from the CPI and PPI data released this week. Last week, the U.S. Senate entered its summer recess without voting on the CLARITY Act. Although the final debate vote for the bill is scheduled for September 14, the probability of it passing before the midterm elections remains low.

  • Sources: Trump to Attend Closed-Door Meeting with Crypto Executives at the White House

    On August 15, sources revealed that U.S. President Trump is expected to attend a White House meeting held by the newly established Innovation Committee on Wednesday. The committee consists of executives from the crypto industry as well as leaders from prediction markets and artificial intelligence companies. Sources indicated that the CEOs of companies such as Coinbase, Ripple, Gemini, Robinhood, Polymarket, and Kalshi are members of the U.S. CFTC Innovation Advisory Committee. Before attending the committee's first official meeting on Thursday, these crypto industry CEOs will gather at the White House for the meeting on Wednesday. Attendees learned that Trump plans to participate in this meeting. The meeting is expected to take place at the Eisenhower Executive Office Building next to the White House, aiming to initiate policy discussions on several key directions in the U.S. innovation sector. Sources also stated that CFTC Chairman Mike Selig and other policy advisors are expected to attend the meeting. One source further revealed that U.S. Treasury Secretary Scott Bessent and Commerce Secretary Howard Lutnick may also be present. The White House spokesperson has not yet responded to requests for comments regarding the meeting arrangements.

  • U.S. Optical Communication Stocks Rise, Lumentum Up Over 6%

    On August 14, U.S. optical communication stocks collectively rose, with Applied Optoelectronics increasing by over 14%, AXT Inc and MaxLinear rising by over 7%, POET Technologies and Lumentum up by over 6%, and Lightwave Logic increasing by over 5%. Corning and Tower Semiconductor also saw gains of over 4%.

  • Dunamu Reports 73% Decrease in Q2 Operating Profit to 23.5 Billion Won

    On August 14, Upbit operator Dunamu announced its Q2 2026 performance, reporting quarterly revenue of 173.5 billion won (approximately 123 million USD) and an operating profit of 23.5 billion won (approximately 16.65 million USD), representing declines of about 26% and 73% respectively compared to Q1. In the first quarter, Dunamu's revenue was 234.6 billion won (approximately 166 million USD) with an operating profit of 88 billion won (approximately 62.34 million USD). Dunamu stated that the decline in performance this quarter was primarily influenced by the overall contraction in liquidity in the global digital asset market, which weakened investor sentiment.