Access Control - Methods

Many components contain methods which require some degree of protected access, so that only appropriate parties can call them. Any public method can have individual access rules set on it, and the system will enforce that those rules are met before allowing the method call to proceed.

In Scrypto, method access control uses the same set of badge-based universal access rules as resource actions do. By default, all public methods are accessible by anyone. In order to enable access control, you define one or more fully-exhaustive AccessRules which set the permissions for every public method in your component, and then apply them to your instantiation.

This is easier to show than to explain. Let’s say you are creating a blueprint which defines three public methods: get_prices(), buy_token(), and collect_profits(). When instantiating, if you don’t specify any rules, all three can be called by anyone. But in this case, you want collect_profits() to be limited to callers who can present a certain admin badge:

// Initialize my struct and instantiate as a local component (not yet in global address space)
let local_component: LocalComponent = Self {
  some_data: some_initial_value
}
.instantiate();

// Define the access rules which will govern access to this component's methods
let access_rules = AccessRules::new()
  .method("collect_profits", rule!(require(my_admin_badge)))
  .default(rule!(allow_all));

// Apply my rules, and add my component to global address space so it can be called by others
let component_address = my_component.add_access_check(access_rules).globalize();

There. Now if anyone tries to call collect_profits() and doesn’t have a Proof of my_admin_badge present in their authorization zone, the system will block the call and the transaction will immediately abort. The other methods are fair game for anyone.

Note that in our AccessRules definition, we supplied a default rule; this is a catch-all to match any method that you didn’t explicitly provide a rule for.

In Scrypto v0.4, the system will allow you to define an AccessRules which does not exhaust all matches (that is, doesn’t include a default rule and doesn’t have an entry for every method). This will be changed in a later version, and you will be required to provide a valid rule for all methods (or include default).

Nothing prevents you from adding multiple AccessRules to a given component. For a given call, each set of rules will be checked, and only if they all pass will the call be permitted.

Setting Up Good "Constructors"

Because it is possible to change method authorization after instantiation but before globalization, when you have a blueprint which has some expected need for certain methods to have privileged access it’s a good habit to provide multiple instantiation methods. At minimum, you should provide one which sets up the access control in the manner you expect (which finishes with a call to globalize() and returns a ComponentAddress), and a second which sets no control rules and leaves that decision up to the instantiator (which finishes with a call to instantiate() and returns a LocalComponent).