Conversation
anegg0
commented
Feb 10, 2026
- Gentle introduction
- Quickstart
- How-to
- Concept
- FAQ
- Troubleshooting
- Reference
- Third-party content
- Not applicable
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
|
||
| 1. A function call doesn't match any existing function signature | ||
| 2. Plain ETH transfer when no `#[receive]` function exists | ||
| 3. The contract receives calldata but no function matches |
There was a problem hiding this comment.
| 3. The contract receives calldata but no function matches | |
| 3. The contract receives calldata, but no function matches |
|
|
||
| ### Accessing VM Context | ||
|
|
||
| All public methods can access blockchain context via `self.vm()`: |
There was a problem hiding this comment.
| All public methods can access blockchain context via `self.vm()`: | |
| All public methods can access the blockchain context via the `self.vm()` property: |
|
|
||
| ## Delegate calls | ||
|
|
||
| Delegate calls allow a contract to execute code from another contract while maintaining its own context. When Contract A executes a delegate call to Contract B, B's code runs using Contract A's storage, `msg.sender`, and `msg.value`. This means any state changes affect Contract A, and the original sender and value of the transaction are preserved. |
There was a problem hiding this comment.
| Delegate calls allow a contract to execute code from another contract while maintaining its own context. When Contract A executes a delegate call to Contract B, B's code runs using Contract A's storage, `msg.sender`, and `msg.value`. This means any state changes affect Contract A, and the original sender and value of the transaction are preserved. | |
| Delegate calls allow a contract to execute code from another contract while maintaining its own context. When Contract A executes a delegate call to Contract B, B's code runs using Contract A's storage, `msg.sender`, and `msg.value`. This means that any state changes affect Contract A, and the original sender and transaction value are preserved. |
|
|
||
| ### Using the low-level `delegate_call` function | ||
|
|
||
| The `delegate_call` function is a low-level operation similar to `call` and `static_call`. It is considered unsafe because it requires trusting the external contract to maintain safety. |
There was a problem hiding this comment.
| The `delegate_call` function is a low-level operation similar to `call` and `static_call`. It is considered unsafe because it requires trusting the external contract to maintain safety. | |
| The `delegate_call` function is a low-level operation similar to `call` and `static_call`. It is considered unsafe because it relies on an external contract to ensure safety. |
|
|
||
| ### Using `RawCall` with `new_delegate()` | ||
|
|
||
| For scenarios requiring untyped calls with more configuration options, `RawCall` offers a fluent interface. You can set up a delegate call by chaining optional configuration methods. |
There was a problem hiding this comment.
| For scenarios requiring untyped calls with more configuration options, `RawCall` offers a fluent interface. You can set up a delegate call by chaining optional configuration methods. | |
| For scenarios that require untyped calls with additional configuration options, `RawCall` provides a fluent interface. You can set up a delegate call by chaining optional configuration methods. |
| ### Safety considerations | ||
|
|
||
| :::caution | ||
| Delegate calls are inherently unsafe and require careful consideration before use. |
There was a problem hiding this comment.
| Delegate calls are inherently unsafe and require careful consideration before use. | |
| Delegate calls are inherently unsafe and should be used with caution. |
|
|
||
| ## Sending ether | ||
|
|
||
| Stylus provides multiple ways to send ether from a contract. Unlike Solidity's `transfer` method which is capped at 2300 gas, Stylus's `transfer_eth` forwards all gas to the recipient. You can cap gas using the low-level `call` method if needed. |
There was a problem hiding this comment.
| Stylus provides multiple ways to send ether from a contract. Unlike Solidity's `transfer` method which is capped at 2300 gas, Stylus's `transfer_eth` forwards all gas to the recipient. You can cap gas using the low-level `call` method if needed. | |
| Stylus provides multiple ways to send ether from a contract. Unlike Solidity's `transfer` method, which is capped at 2300 gas, Stylus's `transfer_eth` forwards all gas to the recipient. You can cap gas using the low-level `call` method if needed. |
| } | ||
| ``` | ||
|
|
||
| ### Using low-level `call()` with value |
There was a problem hiding this comment.
| ### Using low-level `call()` with value | |
| ### Using a low-level `call()` with a value |
| } | ||
| ``` | ||
|
|
||
| ### Where you can send ether |
There was a problem hiding this comment.
| ### Where you can send ether | |
| ### Where can you send `ETH` |
| ### Where you can send ether | ||
|
|
||
| 1. **Externally owned account (EOA) addresses**: Directly send ether to any EOA address | ||
| 2. **Solidity contracts with `receive()` function**: Send ether without calldata to contracts implementing `receive()` |
There was a problem hiding this comment.
| 2. **Solidity contracts with `receive()` function**: Send ether without calldata to contracts implementing `receive()` | |
| 2. **Solidity contracts with the `receive()` function**: Send ether without calldata to contracts implementing `receive()` |
|
|
||
| 1. **Externally owned account (EOA) addresses**: Directly send ether to any EOA address | ||
| 2. **Solidity contracts with `receive()` function**: Send ether without calldata to contracts implementing `receive()` | ||
| 3. **Solidity contracts with `fallback()` function**: Send ether with calldata to contracts implementing `fallback()` |
There was a problem hiding this comment.
| 3. **Solidity contracts with `fallback()` function**: Send ether with calldata to contracts implementing `fallback()` | |
| 3. **Solidity contracts with the `fallback()` function**: Send ether with calldata to contracts implementing `fallback()` |
|
|
||
| ## Factory contract deployment (coming soon) | ||
|
|
||
| The factory pattern allows a contract to deploy other contracts programmatically. This is useful for creating contract instances on-demand, such as deploying new token contracts or creating user-specific vaults. |
There was a problem hiding this comment.
| The factory pattern allows a contract to deploy other contracts programmatically. This is useful for creating contract instances on-demand, such as deploying new token contracts or creating user-specific vaults. | |
| The factory pattern allows a contract to deploy other contracts programmatically. This is useful for creating contract instances on demand, such as deploying new token contracts or creating user-specific vaults. |
| 2. **Entrypoint**: Marks the main contract struct that handles incoming calls | ||
| 3. **Public Methods**: Functions exposed to external callers via the `#[public]` macro | ||
|
|
||
| ### Minimal Contract |
There was a problem hiding this comment.
| ### Minimal Contract | |
| ### Minimal contract |
| - Uses `#[public]` to expose the `user_main` function | ||
| - Returns `ArbResult`, which is `Result<Vec<u8>, Vec<u8>>` | ||
|
|
||
| ## Storage Definition |
There was a problem hiding this comment.
| ## Storage Definition | |
| ## Storage definition |
|
|
||
| Both approaches produce identical storage layouts and are fully interoperable with Solidity contracts using the same storage structure. | ||
|
|
||
| ## The `#[entrypoint]` Macro |
There was a problem hiding this comment.
| ## The `#[entrypoint]` Macro | |
| ## The `#[entrypoint]` macro |
| 2. A `user_entrypoint` function that Stylus calls when the contract receives a transaction | ||
| 3. Method routing logic to dispatch calls to `#[public]` methods | ||
|
|
||
| ## Public Methods with `#[public]` |
There was a problem hiding this comment.
| ## Public Methods with `#[public]` | |
| ## Public methods with `#[public]` |
|
|
||
| The `#[public]` macro exposes Rust methods as external contract functions callable from Solidity, other Stylus contracts, or external callers. | ||
|
|
||
| ### Basic Public Methods |
There was a problem hiding this comment.
| ### Basic Public Methods | |
| ### Basic public methods |
| } | ||
| ``` | ||
|
|
||
| ### State Mutability |
There was a problem hiding this comment.
| ### State Mutability | |
| ### State mutability |
|
|
||
| The `#[constructor]` attribute marks a function that runs once during contract deployment. | ||
|
|
||
| ### Basic Constructor |
There was a problem hiding this comment.
| ### Basic Constructor | |
| ### Basic constructor |
| } | ||
| ``` | ||
|
|
||
| ### Constructor Features |
There was a problem hiding this comment.
| ### Constructor Features | |
| ### Constructor features |
| - Constructor runs exactly once when the contract is deployed | ||
| - Use `tx_origin()` instead of `msg_sender()` when deploying via a factory contract | ||
|
|
||
| ## Method Attributes |
There was a problem hiding this comment.
| ## Method Attributes | |
| ## Method attributes |
| - Easy to test components independently | ||
| - Compatible with Solidity interface standards | ||
|
|
||
| ### Accessing VM Context |
There was a problem hiding this comment.
| ### Accessing VM Context | |
| ### Accessing VM context |
| - Limited to 3 indexed parameters per event | ||
| - Indexed parameters are stored in log topics, not data | ||
|
|
||
| ### Emitting Events |
There was a problem hiding this comment.
| ### Emitting Events | |
| ### Emitting events |
| } | ||
| ``` | ||
|
|
||
| ### Raw Log Emission |
There was a problem hiding this comment.
| ### Raw Log Emission | |
| ### Raw log emission |
| } | ||
| ``` | ||
|
|
||
| ## External Contract Calls |
There was a problem hiding this comment.
| ## External Contract Calls | |
| ## External contract calls |
|
|
||
| Stylus contracts can call other contracts (Solidity or Stylus) using typed interfaces or raw calls. | ||
|
|
||
| ### Defining Contract Interfaces |
There was a problem hiding this comment.
| ### Defining Contract Interfaces | |
| ### Defining contract interfaces |
| } | ||
| ``` | ||
|
|
||
| ### Calling External Contracts |
There was a problem hiding this comment.
| ### Calling External Contracts | |
| ### Calling external contracts |
|
|
||
| ### Calling External Contracts | ||
|
|
||
| #### View Calls (Read-Only) |
There was a problem hiding this comment.
| #### View Calls (Read-Only) | |
| #### View calls (read-only) |
| } | ||
| ``` | ||
|
|
||
| #### Mutating Calls |
There was a problem hiding this comment.
| #### Mutating Calls | |
| #### Mutating calls |
| } | ||
| ``` | ||
|
|
||
| #### Payable Calls |
There was a problem hiding this comment.
| #### Payable Calls | |
| #### Payable calls |
| } | ||
| ``` | ||
|
|
||
| #### Configuring Gas |
There was a problem hiding this comment.
| #### Configuring Gas | |
| #### Configuring gas |
| } | ||
| ``` | ||
|
|
||
| ### Low-Level Calls |
There was a problem hiding this comment.
| ### Low-Level Calls | |
| ### Low-Level calls |
| - `static_call()`: Read-only call (equivalent to Solidity `staticcall`) | ||
| - `RawCall`: Low-level unsafe calls with fine-grained control | ||
|
|
||
| ## Error Handling |
There was a problem hiding this comment.
| ## Error Handling | |
| ## Error handling |
|
|
||
| Stylus contracts can define and return custom errors using Solidity-compatible error types. | ||
|
|
||
| ### Defining Errors |
There was a problem hiding this comment.
| ### Defining Errors | |
| ### Defining errors |
| } | ||
| ``` | ||
|
|
||
| ### Using Errors in Methods |
There was a problem hiding this comment.
| ### Using Errors in Methods | |
| ### Using errors in methods |
| - Error data includes the error signature and parameters | ||
| - Compatible with Solidity `try/catch` blocks | ||
|
|
||
| ## Complete Example |
There was a problem hiding this comment.
| ## Complete Example | |
| ## Complete example |
|
|
||
| ## Complete Example | ||
|
|
||
| Here's a complete ERC-20-style token contract demonstrating all major features: |
There was a problem hiding this comment.
| Here's a complete ERC-20-style token contract demonstrating all major features: | |
| Here's a complete `ERC-20`-style token contract demonstrating all major features: |
| } | ||
| ``` | ||
|
|
||
| ## Best Practices |
There was a problem hiding this comment.
| ## Best Practices | |
| ## Best practices |
|
|
||
| ## Best Practices | ||
|
|
||
| ### 1. Use Appropriate State Mutability |
There was a problem hiding this comment.
| ### 1. Use Appropriate State Mutability | |
| ### 1. Use appropriate state mutability |
| } | ||
| ``` | ||
|
|
||
| ### 2. Validate Inputs Early |
There was a problem hiding this comment.
| ### 2. Validate Inputs Early | |
| ### 2. Validate inputs early |
| } | ||
| ``` | ||
|
|
||
| ### 3. Use Custom Errors |
There was a problem hiding this comment.
| ### 3. Use Custom Errors | |
| ### 3. Use custom errors |
| } | ||
| ``` | ||
|
|
||
| ### 4. Emit Events for State Changes |
There was a problem hiding this comment.
| ### 4. Emit Events for State Changes | |
| ### 4. Emit events for state changes |
| } | ||
| ``` | ||
|
|
||
| ### 5. Access Control Patterns |
There was a problem hiding this comment.
| ### 5. Access Control Patterns | |
| ### 5. Access control patterns |
| } | ||
| ``` | ||
|
|
||
| ### 6. Gas-Efficient Storage Access |
There was a problem hiding this comment.
| ### 6. Gas-Efficient Storage Access | |
| ### 6. Gas-efficient storage access |
| } | ||
| ``` | ||
|
|
||
| ### 7. Check Effects Interactions Pattern |
There was a problem hiding this comment.
| ### 7. Check Effects Interactions Pattern | |
| ### 7. Check effects interactions pattern |
| } | ||
| ``` | ||
|
|
||
| ### 8. Use Type-Safe Interfaces for External Calls |
There was a problem hiding this comment.
| ### 8. Use Type-Safe Interfaces for External Calls | |
| ### 8. Use type-safe interfaces for external calls |
| } | ||
| ``` | ||
|
|
||
| ## See Also |
There was a problem hiding this comment.
| ## See Also | |
| ## See also |
| - [Primitives](./data-types/primitives.mdx) - Basic data types | ||
| - [Compound Types](./data-types/compound-types.mdx) - Arrays, structs, tuples | ||
| - [Storage Types](./data-types/storage.mdx) - Persistent storage | ||
| - [Global Variables and Functions](./global-variables-and-functions.mdx) - VM context methods |
There was a problem hiding this comment.
| - [Global Variables and Functions](./global-variables-and-functions.mdx) - VM context methods | |
| - [Global Variables and Functions](./global-variables-and-functions.mdx): VM context methods |
|
|
||
| - [Primitives](./data-types/primitives.mdx) - Basic data types | ||
| - [Compound Types](./data-types/compound-types.mdx) - Arrays, structs, tuples | ||
| - [Storage Types](./data-types/storage.mdx) - Persistent storage |
There was a problem hiding this comment.
| - [Storage Types](./data-types/storage.mdx) - Persistent storage | |
| - [Storage Types](./data-types/storage.mdx): Persistent storage |
| ## See Also | ||
|
|
||
| - [Primitives](./data-types/primitives.mdx) - Basic data types | ||
| - [Compound Types](./data-types/compound-types.mdx) - Arrays, structs, tuples |
There was a problem hiding this comment.
| - [Compound Types](./data-types/compound-types.mdx) - Arrays, structs, tuples | |
| - [Compound Types](./data-types/compound-types.mdx): Arrays, structs, tuples |
|
|
||
| ## See Also | ||
|
|
||
| - [Primitives](./data-types/primitives.mdx) - Basic data types |
There was a problem hiding this comment.
| - [Primitives](./data-types/primitives.mdx) - Basic data types | |
| - [Primitives](./data-types/primitives.mdx): Basic data types |
pete-vielhaber
left a comment
There was a problem hiding this comment.
Minor nits; should we use ETH or ether across the board? IIRC we do use both, just a thought we should make it consistent across a page.