Arbitrum Stylus logo

Stylus by Example

Constants

Constants are values that are bound to a name and cannot change. They are always immutable. In Rust, constants are declared with the const keyword. Unlike variables declared with the let keyword, constants must be annotated with their type.

Constants are valid for the entire length of the transaction. They are essentially inlined wherever they are used, meaning that their value is copied directly into whatever context invokes them.

Since their value is hardcoded, they can save on gas cost as their value does not need to be fetched from storage.

Learn More

src/main.rs

1#![no_main]
2#![no_std]
3extern crate alloc;
4
5#[global_allocator]
6static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
7
8use alloc::vec;
9use alloc::vec::Vec;
10
11use stylus_sdk::alloy_primitives::Address;
12use stylus_sdk::prelude::*;
13use stylus_sdk::storage::StorageAddress;
14
15// Consts must be 'static, so Rust primitives work well
16// Addresses are 20 bytes long, this one is 'checksummed'
17const OWNER: &str = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
18
19#[solidity_storage]
20#[entrypoint]
21pub struct Contract {
22    owner: StorageAddress,
23}
24
25#[external]
26impl Contract {
27    // Sets the owner to the OWNER const set above
28    pub fn init(&mut self) -> Result<(), Vec<u8>> {
29        // Parse the const hex &str as a local Address variable
30        let owner_address = Address::parse_checksummed(OWNER, None).expect("Invalid address");
31
32        // Save the result as the owner
33        self.owner.set(owner_address);
34
35        Ok(())
36    }
37
38    // Returns the current owner
39    pub fn owner(&self) -> Result<Address, Vec<u8>> {
40        let owner_address = self.owner.get();
41
42        Ok(owner_address)
43    }
44}
1#![no_main]
2#![no_std]
3extern crate alloc;
4
5#[global_allocator]
6static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
7
8use alloc::vec;
9use alloc::vec::Vec;
10
11use stylus_sdk::alloy_primitives::Address;
12use stylus_sdk::prelude::*;
13use stylus_sdk::storage::StorageAddress;
14
15// Consts must be 'static, so Rust primitives work well
16// Addresses are 20 bytes long, this one is 'checksummed'
17const OWNER: &str = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
18
19#[solidity_storage]
20#[entrypoint]
21pub struct Contract {
22    owner: StorageAddress,
23}
24
25#[external]
26impl Contract {
27    // Sets the owner to the OWNER const set above
28    pub fn init(&mut self) -> Result<(), Vec<u8>> {
29        // Parse the const hex &str as a local Address variable
30        let owner_address = Address::parse_checksummed(OWNER, None).expect("Invalid address");
31
32        // Save the result as the owner
33        self.owner.set(owner_address);
34
35        Ok(())
36    }
37
38    // Returns the current owner
39    pub fn owner(&self) -> Result<Address, Vec<u8>> {
40        let owner_address = self.owner.get();
41
42        Ok(owner_address)
43    }
44}

Cargo.toml

1[package]
2name = "constants"
3version = "0.1.0"
4edition = "2021"
5
6[dependencies]
7# Note: Do not deploy to prod with debug flag set
8stylus-sdk = { version = "0.4.2", features = ["debug"] }
9wee_alloc = "0.4.5"
10alloy-sol-types = "0.3.1"
11
12[features]
13export-abi = ["stylus-sdk/export-abi"]
14
15[profile.release]
16codegen-units = 1
17strip = true
18lto = true
19panic = "abort"
20opt-level = "s"
21
22[workspace]
1[package]
2name = "constants"
3version = "0.1.0"
4edition = "2021"
5
6[dependencies]
7# Note: Do not deploy to prod with debug flag set
8stylus-sdk = { version = "0.4.2", features = ["debug"] }
9wee_alloc = "0.4.5"
10alloy-sol-types = "0.3.1"
11
12[features]
13export-abi = ["stylus-sdk/export-abi"]
14
15[profile.release]
16codegen-units = 1
17strip = true
18lto = true
19panic = "abort"
20opt-level = "s"
21
22[workspace]