Skip to main content

Deploy Your Stylus Smart Contracts

To deploy your Stylus smart contracts to Arbitrum networks, there are a few things you need to adjust.

1. Configure your networkโ€‹

Scaffold-Stylus supports Arbitrum networks by default. You can configure your deployment network using environment variables.

Local Network Setupโ€‹

For local development, you need to start a local Stylus-compatible network first:

yarn chain

This command starts a local Stylus-compatible network using the Nitro dev node script (./nitro-devnode/run-dev-node.sh). The network runs on your local machine and can be used for testing and development. You can customize the Nitro dev node configuration in the vendored nitro-devnode directory.

Note: If you encounter an execution reverted error when deploying larger contracts locally, see the Devnode Troubleshooting section below.

Available Networksโ€‹

This template supports Arbitrum and it's orbit networks only. You can test which networks are available and their RPC URLs:

yarn info:networks

This will show you all supported networks and their corresponding RPC endpoints.

For testnet information, including faucets and RPC endpoints, see the Arbitrum Stylus testnet documentation.

Arbitrum Testnet Faucetsโ€‹

To get testnet ETH for deploying and testing your contracts on Arbitrum Sepolia, you can use the following faucets:

2. Deploy your Stylus smart contract(s)โ€‹

Deployment Optionsโ€‹

Scaffold-Stylus supports deploying to different types of networks:

  • Local Network: For development and testing
  • Standard Arbitrum Networks: Sepolia, Mainnet, Nova
  • Orbit Chains: Custom Layer 2 or Layer 3 solutions (requires special configuration)

Deploy to Local Networkโ€‹

The simplest way to deploy your Stylus smart contract is using:

yarn deploy

This command deploys a test smart contract to the local network. The contract is located in packages/stylus/contracts/your-contract/src and can be modified to suit your needs. The yarn deploy command uses the deploy script located in packages/stylus/scripts to deploy the contract to the network. You can also customize the deploy script.

Create Your Own Contractโ€‹

Scaffold-Stylus enables you to create and deploy multiple contracts within a single project. Follow the steps below to create and deploy your own contracts.

Step 1: Generate New Contractโ€‹

Use the following command to create a new contract and customize it as needed:

yarn new-module <contract-name>

The generated contract will be located in packages/stylus/contracts/<contract-name>.

Step 2: Deploy Your Contractโ€‹

yarn deploy [...options]

This command runs the deploy.ts script located in packages/stylus/scripts. You can customize this script with your deployment logic.

Available Options:

  • --network <network>: Specify which network to deploy to
  • --estimate-gas: Only perform gas estimation without deploying
  • --max-fee=<maxFee>: Set maximum fee per gas in gwei

Note: Deployment information is automatically saved in packages/stylus/deployments by default.

Check Your Programโ€‹

Before deploying to live networks, you can check that your program compiles to valid WASM for Stylus and will succeed a deployment onchain without transacting:

cargo stylus check

This command performs a comprehensive check of your contract, including:

  • Contract size validation: Verifies your contract is within deployment limits
  • WASM compilation: Ensures your Rust code compiles to valid WebAssembly
  • Deployment hash: Computes the project metadata hash for deployment
  • WASM data fee estimation: Estimates the cost to deploy your contract

Understanding the Outputโ€‹

When you run cargo stylus check, you'll see output similar to:

Finished `release` profile [optimized] target(s) in 0.13s
stripped custom section from user wasm to remove any sensitive data
contract size: 29.4 KiB (30067 bytes)
wasm size: 105.0 KiB (107494 bytes)
File used for deployment hash: ./Cargo.lock
File used for deployment hash: ./Cargo.toml
...
project metadata hash computed on deployment: "5689e6d67160b086024020d794535313e1411343d0b45565e75ddc055efca5f0"
wasm data fee: 0.000202 ETH (originally 0.000168 ETH with 20% bump)

Contract Size Indicatorsโ€‹

Pay attention to the contract size output color:

  • ๐Ÿ”ด Red: Contract size exceeds the traditional 24KB limit. While older tooling flagged this as a hard limit, Stylus now supports deploying larger contracts as multiple fragments. If your contract is red and deploying to a local devnode fails with execution reverted, see the Devnode Troubleshooting section to ensure your network supports ArbOS 60.

Contract size exceeds limitations

  • ๐ŸŸก Yellow/๐ŸŸข Green: Contract size is within the 24KB single-fragment limit - OK to deploy.

Contract size within acceptable limits

Even though multi-fragment deployment is now supported on ArbOS 60 networks, optimizing your contract code to reduce its size is still recommended to save on deployment costs.

Important

When using constructors in your contract, error logs may not be visible during deployment because constructor errors are compiled into the contract. If deployment fails without clear error messages, check your constructor implementation and consider using an initialize() function instead (especially for Orbit chains).

Note

You can edit your deployment scripts in packages/stylus/scripts/deploy.ts to customize the deployment process.

3. Export ABI for your smart contractโ€‹

If you are using yarn deploy, the script will automatically export the ABI to packages/nextjs/contracts/deployedContracts.ts. You can manually export the ABI for your Stylus program by using:

yarn export-abi

This outputs a Solidity interface that represents your Rust program:

/**
* This file was automatically generated by Stylus and represents a Rust program.
* For more information, please see [The Stylus SDK](https://github.com/OffchainLabs/stylus-sdk-rs).
*/

// SPDX-License-Identifier: MIT-OR-APACHE-2.0
pragma solidity ^0.8.23;

interface ICounter {
function number() external view returns (uint256);
function setNumber(uint256 new_number) external;
function increment() external;
}

Exporting ABIs uses a feature that is enabled by default in your Cargo.toml:

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

4. Deploy to Other Networksโ€‹

To deploy your contracts to other networks (other than the default local Nitro dev node), you'll need to configure your RPC endpoint and wallet credentials.

Prerequisitesโ€‹

  1. Set up Environment Variables

    Configure your target network's environment variables. Check packages/stylus/.env.example for the complete template and set the appropriate variables for your target network:

    # Example for Sepolia
    ACCOUNT_ADDRESS_SEPOLIA=your_account_address_here
    RPC_URL_SEPOLIA=https://sepolia-rollup.arbitrum.io/rpc
    PRIVATE_KEY_SEPOLIA=your_private_key_here

    # Example for Mainnet
    ACCOUNT_ADDRESS_MAINNET=your_account_address_here
    RPC_URL_MAINNET=https://arb1.arbitrum.io/rpc
    PRIVATE_KEY_MAINNET=your_private_key_here

    Note: If RPC URL is not provided, the system will use the default public RPC URL from that network.

  2. Update Frontend Configuration

    Open packages/nextjs/scaffold.config.ts and update the targetNetworks array to include your target chain. This ensures your frontend connects to the correct network and generates the proper ABI in deployedContracts.ts:

    import * as chains from "./utils/scaffold-stylus/supportedChains";
    // ...
    targetNetworks: [chains.arbitrumSepolia],

Deploy to Standard Networksโ€‹

Once configured, deploy to your target network:

yarn deploy --network <network>

You can also estimate gas costs before deploying:

yarn deploy --network <network> --estimate-gas

Deploy to Orbit Chainsโ€‹

Orbit chains require special configuration and have different requirements than standard Arbitrum networks. For detailed instructions on deploying to Orbit chains, see Deploy to Orbit Chains.

Devnode Troubleshootingโ€‹

execution reverted on Contract Activationโ€‹

If you attempt to deploy a contract to a local devnode and see the following error, your local network may be missing the required ArbOS version:

error: server returned an error response: error code -32000: execution reverted

Why this happens: Stylus contracts larger than 24KB (24576 bytes compressed) are deployed as multiple fragments. Activating a multi-fragment contract requires ArbOS 60. A devnode running an older nitro image boots at ArbOS 59 and the activation reverts, with an error that does not obviously point at ArbOS.

How to fix it: The fix has two parts, and both are required:

  1. Update your nitro-node image: Your devnode must use v3.11.0-a618155 or newer. The image alone is NOT enough, as the devnode boots at ArbOS 59 by default.

  2. Explicitly schedule the ArbOS 60 upgrade: You must execute the upgrade transaction before deploying. You can do this with cast:

    cast send -r $RPC --private-key $PRIVATE_KEY 0x0000000000000000000000000000000000000070 \
    'scheduleArbOSUpgrade(uint64,uint64)' 60 0

    The ArbOS Version Trap: The first argument is the ArbOS version (60), NOT the number reported by ArbSys.arbOSVersion(). Because the devnode's ArbSys reports 114 before the upgrade and 115 after, it is a common mistake to pass 115 to this function. If you do, it will be silently ignored (out of range) and the contract will still revert.

If you are using the default ./nitro-devnode/run-dev-node.sh or ./nitro-devnode/start-chain-with-cors.sh scripts, this is handled for you automatically in Scaffold-Stylus v0.1.17 and later. Ensure your vendored nitro-devnode directory is up to date with the latest release.

Important Security Notes
  • The values in .env.example provide a template for required environment variables
  • Always keep your private key secure and never commit it to version control
  • Consider using environment variable management tools for production deployments