Creating Ownable Contracts in Solidity
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:
- Public- Accessible by anyone
- Private- Accessible by only contracts where they are defined and not by inheriting contracts.
- Protected- Accessible by only contracts where they are defined and by contracts that inherit them.
- Internal- Accessible by only other functions of the contract and not by other people or contracts.
- 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
Attempt to call calculateSum() from a non-owner address (Unsuccessful):
Calling calculateSum() as owner (Successful):
Please Login to comment...