Skip to main content

Troubleshooting Stylus

How does Stylus manage security issues in smart contracts when interacting with so many different languages?

All languages are compiled to WASM for them to be able to work with Stylus. So it just needs to verify that the produced WASM programs behave as they should inside the new virtual machine.

Is there any analogue of the fallback function from Solidity in the Rust Stylus SDK?

Currently there isn't any analogue. However, you can use a minimal entrypoint and perform raw delegate calls, forwarding your calldata. You can find more information in Bytes-in, bytes-out programming and call, static_call and delegate_call.

Why are constructors not yet supported for Stylus contracts?

Constructors use EVM bytecode to initialize state. While one could add EVM bytecode manually to their Stylus deployment, we don't allow WASM execution in the constructor so there's no way to express this in the SDK.

We're working on models that will make init easier, so there might be better solutions available in the future. For now, we suggest calling an init method after deploying.

Is it possible to verify Stylus contracts on the block explorer?

Currently it is not possible to verify contracts compiled to WASM on the block explorer, but we are actively working with providers to have the verification process ready for when Stylus reaches mainnet-ready status.

Do Stylus contracts compile down to EVM bytecode like prior other attempts?

No. Stylus contracts are compiled down to WASM. The user writes a program in Rust / C / C++ which is then compiled down to WebAssembly.

How is a Stylus contract deployed?

Stylus contracts are deployed on chain as a blob of bytes, just like EVM ones. The only difference is that when the contract is executed, instead of invoking the EVM, we invoke a separate WASM runtime. Note that a special EOF-inspired prefix distinguishes Stylus contracts from traditional EVM contracts: when a contract's bytecode starts with the magic 0xEF000000 prefix, it's a Stylus WASM contract.

Is there a new transaction type to deploy Stylus contracts?

You deploy a Stylus contract the same way that Solidity contracts are deployed. There are no special transaction types. As a UX note: a WASM will revert until a special instrumentation operation is performed by a call to the new  ArbWasm precompile, which readies the program for calls on-chain.

You can find instructions for deploying a Stylus contract in our Quickstart.

Do Stylus contracts use a different type of ABI?

Stylus contracts use solidity ABIs. Methods, signatures, logs, calls, etc. work exactly as in the EVM. From a user's / explorer's perspective, it all just looks and behaves like solidity.

Does the Stylus SDK for Rust support custom data structures?

For in-memory usage, you should be able to use any implementation of custom data structures without problems.

For storage usage, it might be a bit more complicated. Stylus uses the EVM storage system, so you'll need to define the data structure on top of it. However, in the SDK there's a storage trait that custom types can implement to back their collections with the EVM state trie. The SDK macros are compatible with them too, although fundamentally it's still a global key-value system.

You can read more about it in the Stylus Rust SDK page.

As an alternative solution, you can use entrypoint-style contracts for your custom data structures.

Is there anything special I need to do whenever Stylus gets upgraded on the chain I'm deployed on?

Stylus smart contracts will need to be re-activated once per year (365 days) or whenever an upgrade to Stylus is rolled out (which will always involve an ArbOS upgrade), even if they are in the cache. This re-activation can be done using cargo-stylus, specifically the cargo stylus activate --address=$ADDR sub-command. cargo-stylus is a cargo sub-command for building, verifying, and deploying Arbitrum Stylus WASM contracts in Rust. Note that the gas fee required to make this call will depend on the current demand for Stylus contract activations at any given moment in time. It is recommended that you estimate the gas and then use that value, or a value slightly higher, to re-activate your Stylus contract.

To stay up to date with proposals, timelines, and statuses of network upgrades to Arbitrum One and Nova, we recommend you subscribe to the Arbitrum Node Upgrade Announcement channel on Telegram, join both the #dev-announcements and #node-runners Discord channels in the Arbitrum Discord server, and follow the official Arbitrum Arbitrum Developers X accounts.

Why do I get an error "no library targets found in package" when trying to compile an old example?

Some of the first Stylus examples were built and deployed using a previous version of cargo-stylus (0.1.x). In that version, Stylus projects were structured as regular Rust binaries.

Since cargo-stylus v0.2.1, Stylus projects are structured as libraries, so when trying to compile old projects you might get an error no library targets found in package.

To solve this, it's usually enough to rename the main.rs file to a lib.rs file.

How can I generate the ABI of my Stylus contract?

The cargo-stylus tool has a command that allows you to export the ABI of your Stylus contract: cargo stylus export-abi.

If you're using the Stylus Rust SDK, you'll need to enable the export-abi feature in your Cargo.toml file like so:

[features]
export-abi = ["stylus-sdk/export-abi"]

You'll also need to have a main.rs file that selects that feature.

This is an example of a main.rs file that allows you to export the abi of the stylus-hello-world example project:

#![cfg_attr(not(feature = "export-abi"), no_main)]

#[cfg(feature = "export-abi")]
fn main() {
stylus_hello_world::main();
}