6

Is there a way for one custom pallet to access the storage or functions from another custom pallet?

For Example:

Pallet 1

#[pallet::storage]
pub(super) type MyValue<T: Config> = StorageValue<_, u64, ValueQuery>;

Pallet 2

pub fn do_something(origin: OriginFor<T>, new_value: u64) -> DispatchResult {
    let _sender = ensure_signed(origin)?;

    let value: u64 = how_to_read_my_value();

    if value < new_value {
        how_to_set_my_value(new_value);
    }

    Ok(())
}    

How could I implement how_to_read_my_value and how_to_set_my_value?

1 Answer 1

7

If you are building a pallet (pallet2) which has a direct dependency on another pallet (pallet1), you can you "tight coupling" inherit pallet1's Config in pallet2's Config definition:

pub trait Config: pallet1::Config {
    ...
}

To access public storage items from pallet1 in pallet2, you then just need to call the appropriate function on that storage item:

let value: u64 = pallet1::MyValue::<T>::get();

if value < new_value {
    pallet1::MyValue::<T>set(new_value);
}

To access other public functions from pallet1 in pallet2, you need to use the Pallet type where these functions are implmented:

pallet1::Pallet::<T>::public_function();

Here is a simple example of two pallets interacting in this way:

pallet1.rs

Note that all the things in this pallet are marked public (pub)

use frame_support::pallet_prelude::*;

#[frame_support::pallet]
mod pallet {
    pub trait Config: system::Config {}

    #[pallet::storage]
    pub(super) type MyValue<T: Config> = StorageValue<_, u64, ValueQuery>;

    // -- snip --
}

impl<T: Config> Pallet<T> {
    pub fn get_value() -> u32 {
        <Something<T>>::get()
    }
}

pallet2.rs

use frame_support::pallet_prelude::*;
use crate::pallet1;

mod pallet {
    pub trait Config: pallet1::Config {
        // -- snip --
    }

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn get_value_directly(_origin: OriginFor<T>) -> Result {
            let value = pallet1::MyValue::<T>::get();
            Ok(())
        }

        pub fn set_value_directly(_origin: OriginFor<T>, value: u32) -> Result {
            pallet1::MyValue::<T>::put(value);
            Ok(())
        }

        pub fn get_value_public_function(_origin: OriginFor<T>) -> Result {
            let value = pallet1::Pallet::<T>::get_value();
            Ok(())
        }
    }
}
2
  • Would there be a way to do it without tight coupling?
    – Squirrel
    Commented Feb 8, 2022 at 21:49
  • 1
    Yes, through traits interfaces you can access other pallets. This is "loose coupling". Let me edit my answer to include that (although the answer might get quite long).
    – Shawn Tabrizi
    Commented Feb 8, 2022 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.