Accounts and permissions.

Account: a simple, human-readable name that can be owned by an individual or a group, and is required to approve and push transactions to the network. Each account has authorities and permissions attached. Every account has two default named permissions:

Owner : symbolizes ownership of an account, can do everything. It can be used to recover another permission that may have been compromised.

: symbolizes ownership of an account, can do everything. It can be used to recover another permission that may have been compromised. Active: can do everything except changing the owner.

The two default permissions.

Authorities are structured in a hierarchy relationship, where the parent can modify the permissions beneath it. For example, the “active” is a child of the “owner”. All other permissions are derived from “active”.

Default (single-sign) Account

By default, the keys for the owner and active both have a weight of 1 and both the owner and active permission have a threshold of 1. This means there is only 1 signature from the key to perform any action required the permission.

Multi-sign Account

The owner permission has a threshold of 2 and has 2 keys which both have a weight of 1. This means the signature of both keys is needed to perform any action that requires the owner permissions.

So far accounts can define named permissions by deriving from higher named permissions. Each named permission defines an authority — a threshold signatures check consisting of keys and/or named permission levels of other accounts. For example:

{"threshold":1,"keys":[{"key":"PUB_KEY","weight":1}]} {"threshold":2,"keys":[],"accounts":[{"permission":{"actor":"bob","permission":"active"},"weight":1},{"permission":{"actor":"stacy","permission":"active"},"weight":1},"waits":[]}

Create an account

An account can be created using cleos command line tool following below syntax.

$ cleos create account <creator> <name> <OwnerKey> <ActiveKey>

Parameters:

creator : The name of the account creating the new account

: The name of the account creating the new account name : The name of the new account

: The name of the new account OwnerKey : The owner public key for the new account

: The owner public key for the new account ActiveKey : The active public key for the new account

Reference: https://developers.eos.io/eosio-cleos/reference#cleos-create-account

Account names must conform to the following guidelines:

Must be less than 13 characters

Can only contain the following symbols: .12345abcdefghijklmnopqrstuvwxyz

Here is an example:

$ cleos create account eosio bob EOS5EzTZZQQxdrDaJAPD9pDzGJZ5bj34HaAb8yuvjFHGWzqV25Dch EOS61chK8GbH4ukWcbom8HgK95AeUfP8MBPn7XRq8FeMBYYTgwmcX

Accounts are stored in the database on RAM, the essential resource of the EOS. The database is all about a list of multi-index tables. Basically, the EOS uses the multi-index account_object and permission_object tables. The account_object table is to store account name mainly used to validate later in another process. Each account has two primary permissions the owner and the active. Once creating an account, the two permissions will be stored in the permission_object table. Each account costs the EOS amount of bytes. To understand how to calculate the actual RAM usage, read this article: https://medium.com/game-x-coin/exclamate-eos-ram-2f53ad14ba6e

Process to create an account

The authorization_manager class is mainly to manage permissions. The eosio_contract is actually a smart contract, that provides a number of interfaces to create accounts, update permissions.

eosio_contract class diagram

The source code is to create a new account provided as below.

Create or updates an account’s permission

Using the active permission on the network that signs the actions daily is very risky!!? So we need set a new permission for desirable actions and use a new key (less important) for this.

$ cleos set account permission <account> <permission> <authority> <parent>

Parameters:

account : 12 character account name

: 12 character account name permission : name of the permission

: name of the permission authority : a public key, JSON string or null[delete]

: a public key, JSON string or null[delete] parent : the parent of the permission (default active)

Reference: https://developers.eos.io/eosio-cleos/reference#cleos-set-account

An authority’s child cannot change its parent. Firstly, it finds the permission in the multi-index tables, if exist it continues to modify this permission. Otherwise, it creates a new one and stores in the multi-index tables as well as adds more ram usage.

Create/update permission

In eosio_contract, the method apply_eosio_updateauth handles the request to create and update permissions.

Create voting permission

For example: creating a new permission named vote that deriving from active.

$ cleos set account permission user vote '{"threshold":1,"keys":[{"key":"EOS5Nn9xVdE1VX2UKs4kq78Vi8DEKWEfdR1pWbrH93BZHZvRboXuP","weight":1}]}' "active" -p user@active

Parameters:

user : the account’s name

: the account’s name vote : the name of the new permission

: the name of the new permission {“threshold”:1,”keys”:[{“key”:”EOS5Nn9xVdE1VX2UKs4kq78Vi8DEKWEfdR1pWbrH93BZHZvRboXuP”,”weight”:1}]} : the new public key with a weight of 1, that belongs to the new permission

: the new public key with a weight of 1, that belongs to the new permission active : the parent permission is the active permission

: the parent permission is the active permission -p user@active : need the active permission to execute this command

To shorten, we replace the JSON string by the public key.

$ cleos set account permission user vote EOS5Nn9xVdE1VX2UKs4kq78Vi8DEKWEfdR1pWbrH93BZHZvRboXuP "active" -p user@active

Create a multi-sign account

Let’s assume we have 3 accounts on the network:

multisign — a multisign account we will configure

— a multisign account we will configure bob — Bob’s personal account

— Bob’s personal account stacy — Stacy’s personal account

Multisign account was initially created with a public key for the owner and the active key.

$ cleos get account multisign

created: 2018-11-29T05:48:52.000

permissions:

owner 1: 1 EOS6CXtFHX9VhTPbd1jRyci9oqhJVS846CjkSJbX2fuUMgNjJqMD7

active 1: 1 EOS6CXtFHX9VhTPbd1jRyci9oqhJVS846CjkSJbX2fuUMgNjJqMD7

To change the active permission, we set the threshold to 1 and gives each of the team’s accounts a weight of 1. This is the active permission so we just specify the active permission for each account. We could have chosen to specify keys instead of accounts which would have used the JSON. However, by using accounts, the account owners are given the flexibility the update their keys and authority structure without having to update the multisign authorities.

$ cleos set account permission multisign active '{"threshold":1,"keys":[],"accounts":[{"permission":{"actor":"bob","permission":"active"},"weight":1},{"permission":{"actor":"stacy","permission":"active"},"weight":1}],"waits":[]}' owner -p multisign@owner

Now the active permissions have been set.

$ cleos get account multisign

created: 2018-11-29T05:48:52.000

permissions:

owner 1: 1 EOS6CXtFHX9VhTPbd1jRyci9oqhJVS846CjkSJbX2fuUMgNjJqMD7

active 1: 1 bob@active, 1 stacy@active

Let’s change the owner permission. It will require the team to participate whenever there’s the need to change any additional authorities in the futures.

$ cleos set account permission multisign owner '{"threshold":2,"keys":[],"accounts":[{"permission":{"actor":"bob","permission":"owner"},"weight":1},{"permission":{"actor":"stacy","permission":"owner"},"weight":1}],"waits":[]}' -p multisign@owner $ cleos get account multisign

permissions:

owner 2: 1 bob@owner, 1 stacy@owner

active 1: 1 bob@active, 1 stacy@active

Deleting permission

We place NULL value to the authority in order to delete this permission.

$ cleos set account permission user vote NULL

Delete permission

The 2 default permissions cannot be deleted. The EOS guarantees the deleted permission is not linked to any authority. When it removes the permission, the RAM usage is removed too.

Authorize for a contract’s action

Each permission need be authorized before it can be used to perform one action. A permission should have a single purpose is better.

$ cleos set action permission <account> <code> <type> <requirement>

Parameters:

account : 12 character account name

: 12 character account name code : the account that owns the actions

: the account that owns the actions type : type of the action

: type of the action requirement : the permission name required for executing the given action

Reference: https://developers.eos.io/eosio-cleos/reference#cleos-set-action-permission

The EOS guarantees the code and the permission exist before creating a permission_link_object. It adds more RAM usage.

Link a permission

Link permission to voting action

We have just created a new permission, which doesn’t have the authority to do anything yet. We need to set the authority to use the action in the EOS contract.

$ cleos set action permission user EOSIO voteproducer vote

Parameters:

user : the account name

: the account name eosio : the smart contract

: the smart contract voteproducer : the action’s name

: the action’s name vote : the named permission

Now the voteproducer action was linked to the vote permission. We can start voting with user@vote permission.

$ cleos push action eosio voteproducer ‘{“voter”:”user”,”proxy”:”ottomagiceos”,”producers”:[]}’ -p user@vote

Delete authorization for action

If we want to unlink this permission with the action, we just set the requirement to NULL.

$ cleos set action permission user eosio voteproducer NULL

This also removes the RAM usage.

Delete a linked permission

Evaluating Permissions

Follow the tutorial to deploy the EOSIO.TOKEN contract. We use the transfer permission instead of the active permission. Then we link this permission to the eosio.token/transfer.

Linked transfer permission

We use the transfer permission to perform this action.

$ cleos push action eosio.token transfer ‘[“user”, “bob”, “5.0000 SYS”, “memo”]’ -p user@transfer

When @user deliveries the transfer action, the EOS will first check the account @user has defined a permission mapping for @eosio.token/transfer . If nothing is found then a mapping for @eosio.token contract will be checked. If no further match is found, then it uses the active permission. Here is the workflow:

Evaluating permission

For understanding in detail how the two permissions are compared, here is the source code:

Reference

https://github.com/EOSIO/Documentation/blob/master/TechnicalWhitePaper.md

https://github.com/EOSIO/eos/tree/master/contracts/eosio.msig

https://developers.eos.io/eosio-nodeos/docs/accounts-and-permissions

https://developers.eos.io/eosio-nodeos/docs/learn-about-wallets-keys-and-accounts-with-cleos

https://steemit.com/eos/@genereos/eos-multisig-tutorial

https://medium.com/@bensig/how-to-setup-special-permission-for-your-eos-account-a5342753ead

By Tin Tran@ Lecle VietNam Blog