In some cases, an eosio.code authorization may be required in order to use external contract actions from within your smart contract’s code. For instance, adding a YOUR_CONTRACT@eosio.code permission with active authority is required to allow your smart contract’s actions to send tokens to other accounts.

PROBLEM

These eosio.code authorizations are often associated to the active permission and therefore will be removed when an account is locked with the accountlock1 utility (in fact, to lock the target account, the utility code replaces the active and owner permissions).

SOLUTION

To maintain the eosio.code authorizations when your account is locked, you just need to specify them as custom permissions and link them to one or more external actions before locking the account.

The account-lock utility will take control of the active and owner permissions of the target account but will keep the custom permission settings unchanged to YOUR_CONTRACT@eosio.code.

Defining custom permissions allows your code to access the required external actions even when locked by the accountlock1 utility.


Example: the eosioblender contract

The eosioblender contract requires an @eosio.code authorization to access the following external actions:

  • eosio.token::transfer
  • eosio::newaccount
  • eosio::delegatebw
  • eosio::buy-ram

In order to allow the smart contract’s code to access these actions, before locking the account with the accountlock1 utility, we create a “transfer” and a “service” custom permissions with authority eosioblender@eosio.code. Next, we link the “transfer” permission to the eosio.token::transfer action and the “service” permission to the eosio::newaccount, eosio::buyram and eosio::delegatebw actions (see picture below).

Now, the accountlock1 tool can be used to lock the eosioblender contract while ensuring that the code has access to the required external actions.

Please note that the custom permissions must be specified in the code containing the external calls.

For example, the “service” permission will be specified in the permission level when calling the eosio::newaccount action:

action(
        permission_level{ _self, "service"_n },
        "eosio"_n,
        "newaccount"_n,
        new_account
).send();

The “transfer” permission will be specified in the permission level when calling the eosio.token::transfer action:

action(
        permission_level{_self, "transfer"_n},
        "eosio.token"_n, 
        "transfer"_n,
        std::make_tuple(_self, to, quantity, string("sent by eosioblender"))
).send();