From da1866a44b841825b28db18e7116496e05621923 Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Thu, 20 Feb 2025 13:32:13 -0600 Subject: [PATCH 01/11] Adding structure of a contract to Rust SDK section --- .../stylus/reference/project-structure.md | 209 ++++++++++++++++++ website/sidebars.js | 5 + 2 files changed, 214 insertions(+) create mode 100644 arbitrum-docs/stylus/reference/project-structure.md diff --git a/arbitrum-docs/stylus/reference/project-structure.md b/arbitrum-docs/stylus/reference/project-structure.md new file mode 100644 index 0000000000..3459ef973c --- /dev/null +++ b/arbitrum-docs/stylus/reference/project-structure.md @@ -0,0 +1,209 @@ +--- +title: "Structure of a Rust Contract" +description: "A quick overview of how contracts are structured with the Stylus Rust SDK" +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. +--- + +Contracts in Rust are similar to contracts in Solidity. Each contract can contain declarations of State Variables, Functions, Function Modifiers, Events, Errors, Struct Types, and Enum Types. In addition, Rust contracts can import third-party packages from [crates.io](https://crates.io) as dependencies and use them for advanced functionality. + +## Project Layout + +In the most basic example, this is how a Rust contract will be organized. The simplest way to get going with a new project is to follow the [Quickstart](https://docs.arbitrum.io/stylus/quickstart) guide, or if you've already installed all dependencies, just run `cargo stylus new ` from your terminal to begin a new project. Once installed, your project will include the following required files: + +``` +- src + - lib.rs + - main.rs +- Cargo.toml +- rust-toolchain.toml +``` + +`src/lib.rs` is the root module of your contract's code. Here, you can import utilities or methods from internal or external modules, define the data layout of your contract's state variables, and define your contract's public API. This module must define a root data struct with the `#[entrypoint]` macro and provide an impl block annotated with `#[public]` to define public or external methods. See [First App](https://stylus-by-example.org/basic_examples/first_app) for an example of this. These macros are used to maintain [Solidity ABI](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#basic-design) compatibility to ensure that Rust contracts work with existing Solidity libraries and tooling. + +`src/main.rs` is typically auto-generated by [cargo-stylus](https://github.com/OffchainLabs/cargo-stylus) and does not usually need to be modified. Its purpose is to assist with the generation of [JSON describing](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#json) your contract's public interface, for use with automated tooling and frontend frameworks. + +`Cargo.toml` is standard file that Rust projects use to define a package's name, repository location, etc as well as import dependencies and define feature and build flags. From here you can define required dependencies such as the [Stylus SDK](https://crates.io/crates/stylus-sdk) itself or import third-party packages from [crates.io](https://crates.io). See [First Steps with Cargo](https://doc.rust-lang.org/cargo/getting-started/first-steps.html) if you are new to Rust. + +`rust-toolchain.toml` is used by public blockchain explorers, like [Arbiscan](https://arbiscan.io/), to assist with source code verification. To ensure that source code can be compiled deterministically, we use this file to include relevant metadata like what version of Rust was used. + +Your contract may also include other dot files (such as `.gitignore`, `.env`, etc), markdown files for docs, or additional subfolders. + +## State Variables + +Like Solidity, Rust contracts are able to define _state variables_. These are variables which are stored on the chain's _state trie_, which is essentially the chain's database. They differ from standard Rust variables in that they must implement the `Storage` trait from the Stylus SDK. This trait is used to layout the data in the trie in a Solidity-compatible fashion. The Stylus SDK provides Storage types for all Solidity primitives out-of-the-box, such as `StorageAddress`, `StorageU256`, etc. See [storage module](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/index.html#structs) for more information. + +When working with state variables, you can either use Rust-style syntax or Solidity-style syntax to define your data schema. The `#[storage]` macro is used to define Rust-style state variables while `sol_storage!` macro is used for Solidity-style state variables. Both styles may have more than one struct but must annotate a single struct as the root struct with `#[entrypoint]` macro. Below are examples of each. + +**Rust-style Schema** + +```rust +use stylus_sdk::{prelude::*, storage::{StorageU256, StorageAddress}}; + +#[storage] +#[entrypoint] +pub struct MyContract { + owner: StorageAddress, + version: StorageU256, +} +``` + +**Solidity-style Schema** + +```rust +use stylus_sdk::{prelude::*}; + +sol_storage! { + #[entrypoint] + pub struct MyContract { + owner: address, + version: uint256, + } +} +``` + +To read from state or write to it, getters and setters are used: + +```rust +let new_count = self.count.get() + U256::from(1); +self.count.set(new_count); +``` + +## Functions + +Contract functions are defined by providing an `impl` block for your contract's `#[entrypoint]` struct and annotating that block with `#[public]` to make the functions part of the contract's public API. The first parameter of each function is `&self`, which references the struct annotated with `#[entrypoint]`, it's used for reading state variables. By default, methods are view-only and cannot mutate state. To make a function mutable and able to alter state, `&mut self` must be used. Internal methods can be defined on a separate impl block for the struct that is not annotated with `#[public]`. Internal methods can access state. + +```rust +// Defines the public, external methods for your contract +// This impl block must be for the #[entrypoint] struct defined prior +#[public] +impl Counter { + // By annotating first arg with &self, this indicates a view function + pub fn get(&self) -> U256 { + self.count.get() + } + + // By annotating with &mut self, this is a mutable public function + pub fn set_count(&mut self, count: U256) { + self.count.set(count); + } +} + +// Internal methods (NOT part of public API) +impl Counter { + fn add(a: U256, b: U256) -> U256 { + a + b + } +} +``` + +## Modules + +Modules are a way to organize code into logical units. While your contract must have a `lib.rs` which defines your entrypoint struct, you can also define utility functions, structs, enums, etc, in modules and import them in to use in your contract methods. + +For example, with this file structure: + +``` +- src + - lib.rs + - main.rs +- utils + - mod.rs +- Cargo.toml +- rust-toolchain.toml +``` + +In `lib.rs`: + +```rust +// import module +mod utils; + +// ..other code +const score = utils::check_score(); +``` + +See [Defining modules](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html) in the Rust book for more info on modules and how to use them. + +## Importing Packages + +Rust has a robust package manager for managing dependencies and importing 3rd party libraries to use in your smart contracts. These packages (called crates in Rust) are located at [crates.io](https://crates.io). To make use of a dependency in your code, you'll need to complete these steps: + +Add the package name and version to your `Cargo.toml`: + +```toml +# Cargo.toml +[package] +# ...package info here + +[dependencies] +rust_decimal = "1.36.0" +``` + +Import the package into your contract: + +```rust +// lib.rs +use rust_decimal_macros::dec; +``` + +Use imported types in your contract: + +```rust +// create a fixed point Decimal value +let price = dec!(72.00); +``` + +See [Using public Rust crates](https://docs.arbitrum.io/stylus/recommended-libraries#using-public-rust-crates) for more important details on using public Rust crates as well as a curated list of crates that tend to work well for smart contract development. + +## Events + +Events are used to publicly log values to the EVM. They can be useful for users to understand what occurred during a transaction while inspecting a transaction on a public explorer, like [Arbiscan](https://arbiscan.io/). + +```rust +sol! { + event HighestBidIncreased(address bidder, uint256 amount); +} + +#[public] +impl AuctionContract { + pub fn bid() { + // ... + evm::log(HighestBidIncreased { + bidder: Address::from([0x11; 20]), + amount: U256::from(42), + }); + } +} +``` + +## Errors + +Errors allow you to define descriptive names for failure situations. These can be useful for debugging or providing users with helpful information for why a transaction may have failed. + +```rust +sol! { + error NotEnoughFunds(uint256 request, uint256 available); +} + +#[derive(SolidityError)] +pub enum TokenErrors { + NotEnoughFunds(NotEnoughFunds), +} + +#[public] +impl Token { + pub fn transfer(&mut self, to: Address, amount: U256) -> Result<(), TokenErrors> { + const balance = self.balances.get(msg::sender()); + if (balance < amount) { + return Err(TokenErrors::NotEnoughFunds(NotEnoughFunds { + request: amount, + available: balance, + })); + } + // .. other code here + } +} +``` diff --git a/website/sidebars.js b/website/sidebars.js index 2e0b866541..7a6db2fd30 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -523,6 +523,11 @@ const sidebars = { id: 'stylus/reference/overview', label: 'Overview', }, + { + type: 'doc', + id: 'stylus/reference/project-structure', + label: 'Structure of a Contract', + }, ...stylusByExampleDocsSidebarSDK, { type: 'doc', From 12eaa73b84af5fb2243f373c30baecbdcfcf98b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Feb 2025 11:51:44 -0800 Subject: [PATCH 02/11] fix: rename file extension to `mdx` --- .../reference/{project-structure.md => project-structure.mdx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename arbitrum-docs/stylus/reference/{project-structure.md => project-structure.mdx} (100%) diff --git a/arbitrum-docs/stylus/reference/project-structure.md b/arbitrum-docs/stylus/reference/project-structure.mdx similarity index 100% rename from arbitrum-docs/stylus/reference/project-structure.md rename to arbitrum-docs/stylus/reference/project-structure.mdx From f5b27843d3957952e8b2c4e80633aa887d2e5f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Feb 2025 11:55:02 -0800 Subject: [PATCH 03/11] fix: reformat --- arbitrum-docs/stylus/reference/project-structure.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index 3459ef973c..65cddbdd5a 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -1,6 +1,6 @@ --- -title: "Structure of a Rust Contract" -description: "A quick overview of how contracts are structured with the Stylus Rust SDK" +title: 'Structure of a Rust Contract' +description: 'A quick overview of how contracts are structured with the Stylus Rust SDK' author: chrisco sme: chrisco sidebar_position: 1 @@ -13,7 +13,7 @@ Contracts in Rust are similar to contracts in Solidity. Each contract can contai In the most basic example, this is how a Rust contract will be organized. The simplest way to get going with a new project is to follow the [Quickstart](https://docs.arbitrum.io/stylus/quickstart) guide, or if you've already installed all dependencies, just run `cargo stylus new ` from your terminal to begin a new project. Once installed, your project will include the following required files: -``` +```shell - src - lib.rs - main.rs From e80672bea178c2ad69bea68e4c6fe7a8559d5e1d Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Mon, 21 Apr 2025 20:23:14 -0500 Subject: [PATCH 04/11] Update arbitrum-docs/stylus/reference/project-structure.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gaël Blanchemain --- arbitrum-docs/stylus/reference/project-structure.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index 65cddbdd5a..bab920b75d 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -9,7 +9,7 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart Contracts in Rust are similar to contracts in Solidity. Each contract can contain declarations of State Variables, Functions, Function Modifiers, Events, Errors, Struct Types, and Enum Types. In addition, Rust contracts can import third-party packages from [crates.io](https://crates.io) as dependencies and use them for advanced functionality. -## Project Layout +## Project layout In the most basic example, this is how a Rust contract will be organized. The simplest way to get going with a new project is to follow the [Quickstart](https://docs.arbitrum.io/stylus/quickstart) guide, or if you've already installed all dependencies, just run `cargo stylus new ` from your terminal to begin a new project. Once installed, your project will include the following required files: From 9d01c3824d19ae83576d6fba4df58e6255d110c5 Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Mon, 21 Apr 2025 20:23:25 -0500 Subject: [PATCH 05/11] Update arbitrum-docs/stylus/reference/project-structure.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gaël Blanchemain --- arbitrum-docs/stylus/reference/project-structure.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index bab920b75d..b11491cf51 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -25,7 +25,7 @@ In the most basic example, this is how a Rust contract will be organized. The si `src/main.rs` is typically auto-generated by [cargo-stylus](https://github.com/OffchainLabs/cargo-stylus) and does not usually need to be modified. Its purpose is to assist with the generation of [JSON describing](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#json) your contract's public interface, for use with automated tooling and frontend frameworks. -`Cargo.toml` is standard file that Rust projects use to define a package's name, repository location, etc as well as import dependencies and define feature and build flags. From here you can define required dependencies such as the [Stylus SDK](https://crates.io/crates/stylus-sdk) itself or import third-party packages from [crates.io](https://crates.io). See [First Steps with Cargo](https://doc.rust-lang.org/cargo/getting-started/first-steps.html) if you are new to Rust. +`Cargo.toml` is a standard file that Rust projects use to define a package's name, repository location, etc, as well as import dependencies and define feature and build flags. From here, you can define required dependencies such as the [Stylus SDK](https://crates.io/crates/stylus-sdk) itself or import third-party packages from [crates.io](https://crates.io). See [First Steps with Cargo](https://doc.rust-lang.org/cargo/getting-started/first-steps.html) if you are new to Rust. `rust-toolchain.toml` is used by public blockchain explorers, like [Arbiscan](https://arbiscan.io/), to assist with source code verification. To ensure that source code can be compiled deterministically, we use this file to include relevant metadata like what version of Rust was used. From 98bf03a02815b03831bbeeb9880e8810ca4819bb Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Mon, 21 Apr 2025 20:23:32 -0500 Subject: [PATCH 06/11] Update arbitrum-docs/stylus/reference/project-structure.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gaël Blanchemain --- arbitrum-docs/stylus/reference/project-structure.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index b11491cf51..02070e486f 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -31,7 +31,7 @@ In the most basic example, this is how a Rust contract will be organized. The si Your contract may also include other dot files (such as `.gitignore`, `.env`, etc), markdown files for docs, or additional subfolders. -## State Variables +## State variables Like Solidity, Rust contracts are able to define _state variables_. These are variables which are stored on the chain's _state trie_, which is essentially the chain's database. They differ from standard Rust variables in that they must implement the `Storage` trait from the Stylus SDK. This trait is used to layout the data in the trie in a Solidity-compatible fashion. The Stylus SDK provides Storage types for all Solidity primitives out-of-the-box, such as `StorageAddress`, `StorageU256`, etc. See [storage module](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/index.html#structs) for more information. From f680a6cee64db00ccc8dbc8eb618347b1f44a4dc Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Mon, 21 Apr 2025 21:14:59 -0500 Subject: [PATCH 07/11] Update arbitrum-docs/stylus/reference/project-structure.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gaël Blanchemain --- arbitrum-docs/stylus/reference/project-structure.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index 02070e486f..2dcb532e28 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -101,7 +101,7 @@ impl Counter { ## Modules -Modules are a way to organize code into logical units. While your contract must have a `lib.rs` which defines your entrypoint struct, you can also define utility functions, structs, enums, etc, in modules and import them in to use in your contract methods. +Modules are a way to organize code into logical units. While your contract must have a `lib.rs` which defines your entrypoint struct, you can also define utility functions, structs, enums, etc., in modules and import them to use in your contract's methods. For example, with this file structure: From 93fbd44d827653fe5ed0aa8079ccae757c93d597 Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Mon, 21 Apr 2025 21:15:07 -0500 Subject: [PATCH 08/11] Update arbitrum-docs/stylus/reference/project-structure.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gaël Blanchemain --- arbitrum-docs/stylus/reference/project-structure.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index 2dcb532e28..7705d737b7 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -127,7 +127,7 @@ const score = utils::check_score(); See [Defining modules](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html) in the Rust book for more info on modules and how to use them. -## Importing Packages +## Importing packages Rust has a robust package manager for managing dependencies and importing 3rd party libraries to use in your smart contracts. These packages (called crates in Rust) are located at [crates.io](https://crates.io). To make use of a dependency in your code, you'll need to complete these steps: From 9ec92ea7b0b1e27a811b3a45539be341750a5c72 Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Mon, 21 Apr 2025 21:15:18 -0500 Subject: [PATCH 09/11] Update arbitrum-docs/stylus/reference/project-structure.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gaël Blanchemain --- arbitrum-docs/stylus/reference/project-structure.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index 7705d737b7..518f020a2e 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -129,7 +129,7 @@ See [Defining modules](https://doc.rust-lang.org/book/ch07-02-defining-modules-t ## Importing packages -Rust has a robust package manager for managing dependencies and importing 3rd party libraries to use in your smart contracts. These packages (called crates in Rust) are located at [crates.io](https://crates.io). To make use of a dependency in your code, you'll need to complete these steps: +Rust has a robust package manager for managing dependencies and importing third-party libraries to use in your smart contracts. These packages (called crates in Rust) are located at [crates.io](https://crates.io). To make use of a dependency in your code, you'll need to complete these steps: Add the package name and version to your `Cargo.toml`: From d7ecdd72692b617529b5b8fce1688b7572f96cb7 Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Mon, 21 Apr 2025 21:16:13 -0500 Subject: [PATCH 10/11] Update arbitrum-docs/stylus/reference/project-structure.mdx Co-authored-by: Jason-W123 <147362502+Jason-W123@users.noreply.github.com> --- arbitrum-docs/stylus/reference/project-structure.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index 518f020a2e..900143a231 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -58,7 +58,7 @@ use stylus_sdk::{prelude::*}; sol_storage! { #[entrypoint] pub struct MyContract { - owner: address, + address owner; version: uint256, } } From ce5e6954e4fae6f8692b6b2d1365561c15f80775 Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Wed, 30 Apr 2025 05:39:38 -0500 Subject: [PATCH 11/11] Addressing GH comments --- arbitrum-docs/stylus/reference/project-structure.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/stylus/reference/project-structure.mdx b/arbitrum-docs/stylus/reference/project-structure.mdx index 900143a231..29542e0c4e 100644 --- a/arbitrum-docs/stylus/reference/project-structure.mdx +++ b/arbitrum-docs/stylus/reference/project-structure.mdx @@ -27,7 +27,7 @@ In the most basic example, this is how a Rust contract will be organized. The si `Cargo.toml` is a standard file that Rust projects use to define a package's name, repository location, etc, as well as import dependencies and define feature and build flags. From here, you can define required dependencies such as the [Stylus SDK](https://crates.io/crates/stylus-sdk) itself or import third-party packages from [crates.io](https://crates.io). See [First Steps with Cargo](https://doc.rust-lang.org/cargo/getting-started/first-steps.html) if you are new to Rust. -`rust-toolchain.toml` is used by public blockchain explorers, like [Arbiscan](https://arbiscan.io/), to assist with source code verification. To ensure that source code can be compiled deterministically, we use this file to include relevant metadata like what version of Rust was used. +`rust-toolchain.toml` is used by public blockchain explorers, like [Arbiscan](https://arbiscan.io/), to assist with source code verification. To ensure that source code can be compiled deterministically, we use this file to include relevant metadata like what version of Rust was used. It can also be used to pin the project to a specific Rust version that it's compatible with. Your contract may also include other dot files (such as `.gitignore`, `.env`, etc), markdown files for docs, or additional subfolders. @@ -71,6 +71,8 @@ let new_count = self.count.get() + U256::from(1); self.count.set(new_count); ``` +See [Storage Data Types](https://stylus-by-example.org/basic_examples/storage_data_types) for more examples of this. + ## Functions Contract functions are defined by providing an `impl` block for your contract's `#[entrypoint]` struct and annotating that block with `#[public]` to make the functions part of the contract's public API. The first parameter of each function is `&self`, which references the struct annotated with `#[entrypoint]`, it's used for reading state variables. By default, methods are view-only and cannot mutate state. To make a function mutable and able to alter state, `&mut self` must be used. Internal methods can be defined on a separate impl block for the struct that is not annotated with `#[public]`. Internal methods can access state. @@ -86,7 +88,7 @@ impl Counter { } // By annotating with &mut self, this is a mutable public function - pub fn set_count(&mut self, count: U256) { + pub fn set_count(&mut self, count: U256) { self.count.set(count); } } @@ -156,7 +158,7 @@ Use imported types in your contract: let price = dec!(72.00); ``` -See [Using public Rust crates](https://docs.arbitrum.io/stylus/recommended-libraries#using-public-rust-crates) for more important details on using public Rust crates as well as a curated list of crates that tend to work well for smart contract development. +Note, not all Rust crates are compatible with Stylus since they need to be compiled to WASM and used in a blockchain context, which is more limited than a desktop application. For instance, the `rand` crate is not usable, as there is no onchain randomness available to smart contracts. In addition, contracts cannot access functions that use networking or filesystem access features. There is also a need to be mindful of the size of the crates you import, since the default contract size limit is 24KB (compressed). Crates that do not use the standard library (`no_std` crates) tend to work best. See [Using public Rust crates](https://docs.arbitrum.io/stylus/recommended-libraries#using-public-rust-crates) for more important details on using public Rust crates as well as a curated list of crates that tend to work well for smart contract development. ## Events