I have two custom pallets pallet1 and pallet2. In pallet1 I have a bunch of calls with assigned weights declared under pallet call macro like this

impl<T: Config> Pallet<T> {

In pallet1 I also have a bunch of public helper functions outside of call macro, they are at the bottom of my pallets code

impl<T: Config> Pallet<T> {
  pub fn do_things(args) -> DispatchResult {}

Now pallet2 can call these helper functions from pallet1 through coupling mechanism


Is there a way to call these functions externally/directly by submitting some extrinsic or other means like state_call rpc or something or the only way to invoke them outside pallet1 is hardcoding calls to these functions in other custom pallets

  • Did you mean using pallet-a to call pallet-b's calls?
    – AurevoirXavier
    Commented Feb 22, 2023 at 6:10
  • You mention pallet-1 twice. Please correct that.
    – b0zero
    Commented Feb 22, 2023 at 6:46
  • I mean if I expose do_things() for other pallets to use, does it make do_things() callable(dispatchable) anyhow? I can hardcode a call pallet1::Pallet::<T>::do_things(args) inside new palletX when I'm writing it. Are there other ways to dispatch do_things()?
    – Derek Shaw
    Commented Feb 22, 2023 at 22:01
  • Not sure I understand propertly what are you trying to do, if you want to make do_things callable externaly why don't turn into an extrinsic?
    – Alex Bean
    Commented Feb 27, 2023 at 11:51
  • @AlexBean Just started learning substrate. One of the tutorials says "using internal functions you don't need to do any kind of authorization for the operations performed because the internal functions are only accessible to you as the runtime developer." However this tutorial deals with one pallet only and does not consider coupling. Tryna understand if I need access control in do_things(). I found another question that contradicts tutorial info but cant comment on it because of low rep here stackoverflow.com/q/70974061/21294431
    – Derek Shaw
    Commented Feb 27, 2023 at 15:47

2 Answers 2


To answer the question of "Do I need to worry about access control for do_things if other pallets can call it?", the answer is no, you don't need to worry. Even though it is accessible from other pallets, only the one deploying an appchain or parachain can choose which pallets exist and what they do. As long as you make sure that there are appropriate access control checks whenever an extrinsic causes pallet2 to call pallet1::do_things, you'll be fine.

For these public non-extrinsic functions to be executed, they need to be a side effect of someone submitting an extrinsic to one of the pallets running in your chain.

In general, for functions that change things to be accessible externally, they need to be caused by an extrinsic. So if this function changes any state, it can't meaningfully be called via RPC alone.


Not sure if this what you are looking for, but you could have a higher abstraction for your do_things, a DoThings trait. Your pallet2 via Config will depend from a higher abstraction DoThings.

Example: Preimage type of Scheduler's pallet config, it is defined as a type requiring QueryPreimage and StorePreimage traits, and one of the implementations of these traits is Preimage pallet.


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.