Authorisation mechanism for smart contract invoking another smart contract

How can I only allow a particular smart contract instance (1) to invoke another smart contract (2)? So in 2 receive function, I can do sometime like in mint example:

ensure!(sender.matches_account(&owner), ContractError::Unauthorized);

I cannot use the hardcoded address of smart contract 1 for checking because at point of coding 2, 1 is not used instanstiated. Also that I can only deploy and instantiate 1 only when I have the address (so deployed and instantiated) of 2 because 1 needs it for invoking 2.

So if address check is not possible, any other way to do this, for example use some other metadata like sender or owner where at least I can enforce that both smart contract are instantiated by same owner? I’d like to avoid the Parameter route – passing the checkable info as part of Param – since that seems like a weak and hackable approach. Thanks!


It sounds like you have an inherently circular setup, where contract 1 must know about address of contract 2 and vice-versa.

One way to achieve this is that

  • you initilize a new instance of 1 in some “paused” state. You need an admin role to change this pause state.
  • you then initialize a new instance of 2, giving it the address of 1
  • you then invoke an entrypoint on 1 to set the address of 2
  • and then unpause/activate 1

Thanks abizjak. How can I put the instance in “pause” or “unpaused” state? But following your suggestion, what I’ve done so far is below (without any state pause):

  • initialize 1 and no one is using it yet so state is fine
  • initialise 2 with address of 1 as part of init param
  • invoke an entry-ointment on 1 to set the address of 2
  • Now 1 and 2 are ready

I will get back when it works out. Thanks