[Ethereum] “onlyOwner” Function restrict the call from child contract

contract-developmentcontract-upgradingimportsolidity

I have a basic knowledge of solidity. I am trying to create an upgradable ERC20 Token. For that, I create TokenStorage contract and Logic contract and trying to write the Proxy contract.

In the Logic contract:

pragma solidity ^0.4.24;
import "./TokenStorage.sol";
import "./SafeMath.sol";
import './Ownable.sol';

In the TokenStorage contract:

function addTotalSupply(uint256 _value) public onlyOwner {
    totalSupply = totalSupply.add(_value);
}

When I call balances.addTotalSupply(_amount) from Logic.mint(), I get error.

If I remove onlyOwner in addTotalSupply, it executes correctly.

Note All contracts are deployed using the same account.

Please help me to understand why this happens.

Please Share me a proper guide to creating an upgradeable ERC20 Token is much appreciable

Thank you.
Sorry for my bad English

Best Answer

Sammu Sundar.

It happens because your Logic contract is not an owner/creator of the Storage contract (from what I understood).

In this case, it would be better to introduce an additional access control mechanism. You may call it manager or admin. The key point is to allow certain operations to be called not only by the owner.

You could use something like this as a base contract for entities that should be managed and owned.

contract Managed is Owned {          

    mapping (address => bool) public managers;

    constructor() public Owned() {
        managers[owner] = true;
    }

    /**@dev Allows execution by managers only */
    modifier managerOnly {
        require(managers[msg.sender]);
        _;
    }

    function setManager(address manager, bool state) public ownerOnly {
        managers[manager] = state;
    }
}

Then just inherit your Storage contract from Managed and add managerOnly modifier instead of onlyOwner to the addTotalSupply. After you deploy both Storage and Logic, connect them by calling.

await storage.setManager(logic.address, true).send({from:owner})
//rest of the code

Hope, that will help.

Related Topic