abstract contract Ownable {
    address private _owner;
    address private _newOwner;
    
    event OwnerShipTransferred(address indexed oldOwner, address indexed newOwner);
    
    /**
     * 
     * @dev Setting the deployer as the initial owner.
     * 
     */
     
    constructor() {
        _owner = msg.sender;
        _newOwner = msg.sender;
        emit OwnerShipTransferred(address(0), _owner);
    }
    
     /**
     * 
     * @dev Returns the address of the current owner.
     * 
     */
    
    function owner() public view returns(address){
        return _owner;
    }
    
    /**
     * 
     * @dev Reverting with message on overflow if called by any account other than the owner.
     * 
     */
    modifier onlyOwner(){
        require(msg.sender == _owner, 'You are not the owner');
        _;
    }
    
    /**
     * 
     * @dev Set new owner to transfer ownership, reverting with message on overflow if account is not the owner
     * 
     */
    function transferOwnership(address newOwner_) public onlyOwner{
        require(newOwner_ != address(0), 'Invalid address');
        _newOwner = newOwner_;
    }
    
    /**
     * 
     * @dev Accept ownership, reverting with message on overflow if account is not the new owner
     * 
     */
    function acceptOwnership()public{
        require(msg.sender == _newOwner, 'You are not the new owner');
        _transferOwnership(_newOwner);
    }
    
    function _transferOwnership(address newOwner_) internal{
        emit OwnerShipTransferred(_owner,newOwner_);
        _owner = newOwner_;
    }
}
/**
 * 
 * @dev Contract that guarantees exclusive access to specific functions for the owner
 * 
 * */
function transferOwnership(address newOwner_) public onlyOwner{
    require(newOwner_ != address(0), 'Invalid address');
    _newOwner = newOwner_;
}

/**
 * 
 * @dev Set new owner to transfer ownership, reverting with message on overflow if account is not the owner
 * 
 */