How to Make a Solidity Contract 100x Cheaper and Faster

Share this article:
How to Make a Solidity Contract 100x Cheaper and Faster

If you've built on Ethereum, you know the drill: everything lives in Solidity. That means when you want to do something more compute-heavy, like run advanced math or cryptography, you end up paying high gas costs. Each step, whether arithmetic, memory access, or a state read or write, is metered in the EVM. That makes small operations inexpensive, but raw compute, such as loops, cryptographic functions, or large memory usage, incurs high costs. You can’t just pull in your favorite Rust library or drop in some optimized C++.

But what if you could?

What if heavy computation could be metered in a much smaller unit, making it more efficient? What if you could reach for other languages without losing the interoperability you already rely on?

Developers are often forced into trade-offs. We can stay in Solidity and accept these costs, or move off into specialized domain-specific languages (DSLs) that break composability. Neither feels great.

It doesn't have to be that way.

The Stylus MultiVM

Stylus changes this by introducing the MultiVM on Arbitrum. You get the EVM and a WebAssembly (Wasm) virtual machine running side by side, both sharing the same state tree.

That means there are no silos: A Rust contract compiled to Wasm looks just like other code on the chain. Solidity can call it directly. The interoperability is built in at the protocol level. Since Wasm executes much more efficiently, Stylus measures its operations in ink, a unit smaller than gas that makes it possible to price compute and memory more precisely.

Under the hood, the system decides which VM to use based on a contract's header. If it's EVM bytecode, it runs on the EVM. If it's Wasm, it runs in Wasmer, the execution engine used by Stylus. Both paths feed into the same ABI layer and update the same state tree, so from a developer perspective, a cross-VM call looks just like any other contract call.

Visualization of Execution Paths based on a Header Check

The result is that Solidity contracts and Stylus contracts run in parallel, allowing them to call each other seamlessly.

Calling Stylus from Solidity

Let's take a look at how this works.

Suppose you've deployed an NFT contract written for the Stylus VM using the Stylus Rust SDK. You want to mint tokens from a Solidity contract. Here's how you'd do it:

pragma solidity ^0.8.0;

interface IStylusNFT {
    function mint(address to, uint256 tokenId) external;
}

contract NFTCaller {
    IStylusNFT public stylusNFT;

    constructor(address stylusNFTAddress) {
        stylusNFT = IStylusNFT(stylusNFTAddress);
    }

    function mintFromSolidity(address to, uint256 tokenId) external {
        stylusNFT.mint(to, tokenId);
    }
}

That's it. To Solidity, the Stylus NFT contract is simply another address that implements the mint function. There's no bridging or glue code. The EVM and Wasm VMs both live under Arbitrum Nitro, and they share the same account model.

This interoperability opens the door to new designs. You can keep your Solidity contracts as the familiar interface for the basic functionality of your application, while moving gas-intensive logic into Rust for huge efficiency gains. You don't lose composability, and you don't abandon the EVM ecosystem.

With Stylus, you don't need to debate the classic trade-off we began with. Both Solidity and the higher-performance language of your choice can work in tandem to produce the best results for your needs. No painful compromises needed.

Learn More

If you want to go deeper into building interoperable applications with Solidity and Stylus, here are a few good places to start:

Read more