Skip to content

docs: add fallback and receive function documentation for Stylus Rust SDK 0.7.0+ #2266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions arbitrum-docs/partials/_troubleshooting-stylus-partial.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ All languages are compiled to WASM for them to be able to work with Stylus. So i

### Is there any analogue of the fallback function from Solidity in the Rust Stylus SDK?
<p>
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 <a href="https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#bytes-in-bytes-out-programming">Bytes-in, bytes-out programming</a> and <a href="https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#call-static_call-and-delegate_call">call, static_call and delegate_call</a>.
Yes, starting with SDK version 0.7.0, the Router trait supports both `fallback` and `receive` methods, similar to their Solidity counterparts. The `fallback` method is called when a transaction has calldata that doesn't match any defined function, while the `receive` method is called when a transaction has empty calldata. You can find more information in <a href="https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#fallback-and-receive-functions">Fallback and receive functions</a>.
</p>

<p>

For older SDK versions (pre-0.7.0), you can use a minimal entrypoint and perform raw delegate calls, forwarding your calldata. You can find more information in <a href="https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#bytes-in-bytes-out-programming">Bytes-in, bytes-out programming</a> and <a href="https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#call-static_call-and-delegate_call">call, static_call and delegate_call</a>.
</p>


Expand Down
33 changes: 33 additions & 0 deletions arbitrum-docs/stylus/reference/rust-sdk-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,39 @@ sol_storage! {
}
```

### Fallback and receive functions

Starting with SDK version 0.7.0, the [`Router`](https://docs.rs/stylus-sdk/latest/stylus_sdk/abi/trait.Router.html) trait supports the `fallback` and `receive` methods, which work similar to their Solidity counterparts:

- [`fallback`](https://docs.rs/stylus-sdk/latest/stylus_sdk/abi/trait.Router.html#tymethod.fallback): This method is called when a transaction is sent to the contract with calldata that doesn't match any function signature. It serves as a catch-all function for contract interactions that don't match any defined interface.

- [`receive`](https://docs.rs/stylus-sdk/latest/stylus_sdk/abi/trait.Router.html#tymethod.receive): This method is called when a transaction is sent to the contract with no calldata (empty calldata). It allows the contract to receive ETH.

Here's an example implementation:

```rust
#[public]
impl Contract {
// Automatically called when transaction has calldata that doesn't match any function
#[fallback]
#[payable]
pub fn fallback(&mut self, calldata: Vec<u8>) -> Result<Vec<u8>, Vec<u8>> {
// Handle arbitrary calldata
Ok(Vec::new()) // Return empty response or custom response data
}

// Automatically called when transaction has empty calldata
#[receive]
#[payable]
pub fn receive(&mut self) -> Result<(), Vec<u8>> {
// Handle ETH receiving logic
Ok(())
}
}
```

Both methods can be annotated with `#[payable]` to accept ETH along with the transaction. Without this annotation, transactions that send ETH will be rejected.

## Calls

Just as with storage and functions, Stylus SDK calls are Solidity ABI equivalent. This means you never have to know the implementation details of other contracts to invoke them. You simply import the Solidity interface of the target contract, which can be auto-generated via the `cargo stylus` [CLI tool](https://github.com/OffchainLabs/cargo-stylus#exporting-solidity-abis).
Expand Down
2 changes: 1 addition & 1 deletion website/static/building-stylus-faqs.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{"question": "How does Stylus manage security issues in smart contracts when interacting with so many different languages?","answer": "<p>\nAll 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.\n</p>\n\n<p>\n\n</p>\n\n","key": "how-does-stylus-manage-security-issues-in-smart-contracts-when-interacting-with-so-many-different-languages"},
{"question": "Is there any analogue of the fallback function from Solidity in the Rust Stylus SDK?","answer": "<p>\nCurrently 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 <a href=\"https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#bytes-in-bytes-out-programming\">Bytes-in, bytes-out programming</a> and <a href=\"https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#call-static_call-and-delegate_call\">call, static_call and delegate_call</a>.\n</p>\n\n<p>\n\n</p>\n\n","key": "is-there-any-analogue-of-the-fallback-function-from-solidity-in-the-rust-stylus-sdk"},
{"question": "Is there any analogue of the fallback function from Solidity in the Rust Stylus SDK?","answer": "<p>\nYes, starting with SDK version 0.7.0, the Router trait supports both `fallback` and `receive` methods, similar to their Solidity counterparts. The `fallback` method is called when a transaction has calldata that doesn't match any defined function, while the `receive` method is called when a transaction has empty calldata. You can find more information in <a href=\"https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#fallback-and-receive-functions\">Fallback and receive functions</a>.\n</p>\n\n<p>\nFor older SDK versions (pre-0.7.0), you can use a minimal entrypoint and perform raw delegate calls, forwarding your calldata. You can find more information in <a href=\"https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#bytes-in-bytes-out-programming\">Bytes-in, bytes-out programming</a> and <a href=\"https://docs.arbitrum.io/stylus/reference/rust-sdk-guide#call-static_call-and-delegate_call\">call, static_call and delegate_call</a>.\n</p>\n\n<p>\n\n</p>\n\n","key": "is-there-any-analogue-of-the-fallback-function-from-solidity-in-the-rust-stylus-sdk"},
{"question": "Why are constructors not yet supported for Stylus contracts?","answer": "<p>\nConstructors 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.\n</p>\n\n<p>\nWe'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.\n</p>\n\n<p>\n\n</p>\n\n","key": "why-are-constructors-not-yet-supported-for-stylus-contracts"},
{"question": "Is it possible to verify Stylus contracts on the block explorer?","answer": "<p>\nCurrently 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.\n</p>\n\n<p>\n\n</p>\n\n","key": "is-it-possible-to-verify-stylus-contracts-on-the-block-explorer"},
{"question": "Do Stylus contracts compile down to EVM bytecode like prior other attempts?","answer": "<p>\nNo. Stylus contracts are compiled down to WASM. The user writes a program in Rust / C / C++ which is then compiled down to WebAssembly.\n</p>\n\n<p>\n\n</p>\n\n","key": "do-stylus-contracts-compile-down-to-evm-bytecode-like-prior-other-attempts"},
Expand Down
Loading