Arbitrum Stylus logo

Stylus by Example

Mapping

Mappings in Solidity are hash tables that store data as key-value pairs, where the key can be any of the built-in data types supported by Ethereum.

Here we will give you the example of mapping in Stylus Rust SDK.

Maps are created with the syntax StorageMap<keyType, StorageType> (rust syntax) or mapping(keyType => valueType) (solidity syntax).

If you define with rust syntax, the keyType should be the type from alloy_primitives, valueType can be be any type from StorageType.

If you define with solidity syntax, the keyType can be any built-in value type, bytes, string, or any contract, valueType can be any type including another mapping or an array.

Mappings are not iterable.

src/lib.rs

1// Allow `cargo stylus export-abi` to generate a main function.
2#![cfg_attr(not(feature = "export-abi"), no_main)]
3extern crate alloc;
4
5/// Import items from the SDK. The prelude contains common traits and macros.
6use stylus_sdk::{prelude::*, alloy_primitives::{Address, U256}};
7use stylus_sdk::storage::{*};
8
9#[storage]
10#[entrypoint]
11pub struct Mapping {
12    my_map: StorageMap<Address, StorageBool>,
13    my_nested_map: StorageMap<U256, StorageMap<Address, StorageBool>>,
14}
15
16// You can also define mapping storage using the Solidity syntax.
17// sol_storage! {
18//     #[entrypoint]
19//     pub struct Mapping {
20//         mapping(address => bool) my_map;
21//         mapping(uint256 => mapping(address => bool)) my_nested_map;
22//     }
23// }
24
25
26/// Declare that `Mapping` is a contract with the following external methods.
27#[public]
28impl Mapping {
29
30    // First is the simple map ========================================
31
32    pub fn get_my_map(&self, target: Address) -> bool {
33        // Mapping always returns a value.
34        // If the value was never set, it will return the default value.
35        self.my_map.get(target)
36    }
37
38    pub fn set_my_map(&mut self, target: Address, new_value: bool) {
39        // Update the value at this address
40        self.my_map.setter(target).set(new_value);
41    }
42
43    pub fn remove_my_map(&mut self, target: Address) {
44        // Reset the value to the default value.
45        self.my_map.delete(target);
46    }
47
48    // Next is the nested map ========================================
49
50    pub fn get_my_nested_map(&self, index: U256, target: Address) -> bool {
51        // Mapping always returns a value.
52        // If the value was never set, it will return the default value.
53        self.my_nested_map.get(index).get(target)
54    }
55
56    pub fn set_my_nested_map(&mut self, index: U256, target: Address, new_value: bool) {
57        // Update the value at this address
58        self.my_nested_map.setter(index).setter(target).set(new_value);
59    }
60
61    pub fn remove_my_nested_map(&mut self, index: U256, target: Address) {
62        // Reset the value to the default value.
63        self.my_nested_map.setter(index).delete(target);
64    }
65}
1// Allow `cargo stylus export-abi` to generate a main function.
2#![cfg_attr(not(feature = "export-abi"), no_main)]
3extern crate alloc;
4
5/// Import items from the SDK. The prelude contains common traits and macros.
6use stylus_sdk::{prelude::*, alloy_primitives::{Address, U256}};
7use stylus_sdk::storage::{*};
8
9#[storage]
10#[entrypoint]
11pub struct Mapping {
12    my_map: StorageMap<Address, StorageBool>,
13    my_nested_map: StorageMap<U256, StorageMap<Address, StorageBool>>,
14}
15
16// You can also define mapping storage using the Solidity syntax.
17// sol_storage! {
18//     #[entrypoint]
19//     pub struct Mapping {
20//         mapping(address => bool) my_map;
21//         mapping(uint256 => mapping(address => bool)) my_nested_map;
22//     }
23// }
24
25
26/// Declare that `Mapping` is a contract with the following external methods.
27#[public]
28impl Mapping {
29
30    // First is the simple map ========================================
31
32    pub fn get_my_map(&self, target: Address) -> bool {
33        // Mapping always returns a value.
34        // If the value was never set, it will return the default value.
35        self.my_map.get(target)
36    }
37
38    pub fn set_my_map(&mut self, target: Address, new_value: bool) {
39        // Update the value at this address
40        self.my_map.setter(target).set(new_value);
41    }
42
43    pub fn remove_my_map(&mut self, target: Address) {
44        // Reset the value to the default value.
45        self.my_map.delete(target);
46    }
47
48    // Next is the nested map ========================================
49
50    pub fn get_my_nested_map(&self, index: U256, target: Address) -> bool {
51        // Mapping always returns a value.
52        // If the value was never set, it will return the default value.
53        self.my_nested_map.get(index).get(target)
54    }
55
56    pub fn set_my_nested_map(&mut self, index: U256, target: Address, new_value: bool) {
57        // Update the value at this address
58        self.my_nested_map.setter(index).setter(target).set(new_value);
59    }
60
61    pub fn remove_my_nested_map(&mut self, index: U256, target: Address) {
62        // Reset the value to the default value.
63        self.my_nested_map.setter(index).delete(target);
64    }
65}

Cargo.toml

1[package]
2name = "stylus-mapping-example"
3version = "0.1.7"
4edition = "2021"
5
6[dependencies]
7alloy-primitives = "=0.7.6"
8alloy-sol-types = "=0.7.6"
9stylus-sdk = "0.6.0"
10hex = "0.4.3"
11
12[dev-dependencies]
13tokio = { version = "1.12.0", features = ["full"] }
14ethers = "2.0"
15eyre = "0.6.8"
16
17[features]
18export-abi = ["stylus-sdk/export-abi"]
19
20[lib]
21crate-type = ["lib", "cdylib"]
1[package]
2name = "stylus-mapping-example"
3version = "0.1.7"
4edition = "2021"
5
6[dependencies]
7alloy-primitives = "=0.7.6"
8alloy-sol-types = "=0.7.6"
9stylus-sdk = "0.6.0"
10hex = "0.4.3"
11
12[dev-dependencies]
13tokio = { version = "1.12.0", features = ["full"] }
14ethers = "2.0"
15eyre = "0.6.8"
16
17[features]
18export-abi = ["stylus-sdk/export-abi"]
19
20[lib]
21crate-type = ["lib", "cdylib"]