Open In App

Creating Ownable Contracts in Solidity

Improve
Improve
Like Article
Like
Save
Share
Report

A Smart Contract (or crypto contract) is a computer program that directly and automatically controls the transfer of digital assets between the parties under certain conditions. Once deployed, a smart contract code cannot be changed. It is also publicly visible to everyone. 
Solidity is a language used for creating smart contracts which is then compiled to a byte code which in turn is deployed on the Ethereum network. Even though, the code is publicly visible, the calling of functions can be restricted using modifiers.
Solidity provides some access modifiers by default:

  1. Public- Accessible by anyone
  2. Private- Accessible by only contracts where they are defined and not by inheriting contracts.
  3. Protected- Accessible by only contracts where they are defined and by contracts that inherit them.
  4. Internal- Accessible by only other functions of the contract and not by other people or contracts.
  5. External- Accessible by only other people or contracts and not by functions.

Need of Ownable Contracts:
Some functions are necessary for only configuration purposes or one-time calculations. Such functions if exposed publicly can be used maliciously or mistakenly to exhaust gas. To prevent misuse or reduce gas cost, such functions must be restricted to only selected external addresses (for simplicity, owner). To solve this, ownable contracts can be used.
Following is the code for an ownable contract. It can be inherited by other contracts which intend to have ownable modifiers for selected functions.
Below is the Solidity program for the above approach:

Solidity




// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0;
  
contract Ownable 
{    
  // Variable that maintains 
  // owner address
  address private _owner;
  
  // Sets the original owner of 
  // contract when it is deployed
  constructor()
  {
    _owner = msg.sender;
  }
  
  // Publicly exposes who is the
  // owner of this contract
  function owner() public view returns(address) 
  {
    return _owner;
  }
  
  // onlyOwner modifier that validates only 
  // if caller of function is contract owner, 
  // otherwise not
  modifier onlyOwner() 
  {
    require(isOwner(),
    "Function accessible only by the owner !!");
    _;
  }
  
  // function for owners to verify their ownership. 
  // Returns true for owners otherwise false
  function isOwner() public view returns(bool
  {
    return msg.sender == _owner;
  }
}
  
contract OwnableDemo is Ownable 
    uint sum = 0;
    uint[] numbers;
  
    // Push number to array
    function addNumber(uint number) public
    {
        numbers.push(number);
    }
  
    // Read sum variable
    function getSum() public view returns(uint)
    {
        return sum;
    }
  
    /* 
        Calculate sum by traversing array
        The onlyOwner modifier used here prevents 
        this function to be called by people other 
        than owner who deployed it
    */
    function calculateSum() onlyOwner public
    {
        sum = 0;
        for(uint i = 0;  
                 i < numbers.length; i++)
            sum += numbers[i];
    }
}


Output:
Adding numbers from any address (owner or not doesn’t matter): 
The function was called thrice with arguments: 5, 6, and 2 respectively

Output#1

Attempt to call calculateSum() from a non-owner address (Unsuccessful):

Output#2

Calling calculateSum() as owner (Successful):

Output#3



Last Updated : 11 May, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads