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.

Why do I get an error "no library targets found in package" when trying to compile and 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();
}