Defining Roles in Smart Contract
Tags: solidity, smartcontract, blockchain
Published: 2020-02-04 04:48:15

This is a quick and short article that I wanted to get out of my drafts.  There is a big presumption over here that you are aware of what blockchain and smart contract is.  If you are not aware of these concepts, I will have to request you to hunt these concepts down or put in a comment below and I will guide you through it.

## Why do we need Roles?

_Fact: Blockchain is like an immutable database._

Given this fact, if you are a dev who is into developing smart contracts specially for the ethereum world, then you are already aware that smart contracts are (by strict definition) not upgradable.  That is to say, once they are deployed they will stay there forever and you will not have the option to modify the code.

With that in mind, Smart Contract developers design different methods in which some functions within the Smart Contracts are only available to certain wallet/public addresses.  

This is mostly from a security point of view.

EG: The most commonly used type of Smart Contract where only a few accounts are permitted to do certain actions are "Multi-Sig Wallets". 

## What are Roles?

In the simplest terms, Roles are like what you would see in a movie/act/play/game.  Each wallet address is assigned a character and each character has a limited set of power or an advantage, depending on what and how you define that character in the Smart Contract.

## How to do it?

Without a doubt, you are free to define your own mechanisms to implement this; however, I find OpenZeppelin's [Roles based framework](https://docs.openzeppelin.com/contracts/2.x/access-control#role-based-access-control) really useful for asap development.

## Quick Code Example

```
pragma solidity ^0.5.0;

import "@openzeppelin/contracts-ethereum-package/contracts/access/Roles.sol";

///@author amateurdev

contract TestingRoles  {
    using Roles for Roles.Role;

    // state variables
    Roles.Role private _adders;
    Roles.Role private _subtractors;

    uint16 public ini_number;

    constructor(address adder, address subtractor, uint16 _ini_number)
        public
    {
        ini_number = _ini_number;
        _adders.add(adder);
        _subctractors.add(subtractor);
    }

    function add(uint16 _number) public returns (uint256) {
        require(_adders.has(msg.sender), "It is not an adder");
        ini_number = ini_number + _number;
        return ini_number;
    }

    function sub(uint16 _number) public returns (uint256) {
        require(_subtractors.has(msg.sender), "It is not an subtractor");
        require(_number <= ini_number);
        ini_number = ini_number - _number;
        return ini_number;
    }

}

```

The above code is a real quick smart contract which will help you test out the power of the Open Zeppelin's Roles Library/Contract.

Essentially, what we are doing is:

- at the time of deployment of this contract
- defining two addresses (ideally should be different) one of which has the 'power' to add and the other one has the 'power' to subtract
- setting up an initial value of the test/dummy number

Post the deployment, (obviously) only the adders will be able to add and only the subtractors will be able to reduce the number.

_I am not going into how to deploy it or test it, with the objective to not drag this article._

## How is this helpful?

(a) I cannot thank enough to [Open Zeppelin](https://openzeppelin.com/) and their team for doing the basic groundwork. Using Open Zeppelin's infrastructure, the development time for Smart Contract is like half of what it would take otherwise.  Above is a quick example of that.

(b) I keep facing situations where I have to develop Smart Contracts in which different parties are involved which have different vested interests.  Thus, using the above, I am able to define functions that can be used by the respective parties within their limitations.