contract Ownable {
    address private _owner;

    event OwnershipTransferred(address previousOwner, address newOwner);
    
    /**
     * Constructor
     * @param addr The owner of the smart contract
     */
    constructor (address addr) {
        require(addr != address(0), "The address of the owner cannot be the zero address");
        require(addr != address(1), "The address of the owner cannot be the ecrecover address");
        _owner = addr;
        emit OwnershipTransferred(address(0), addr);
    }

    /**
     * @notice This modifier indicates that the function can only be called by the owner.
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(msg.sender), "Only the owner of the smart contract is allowed to call this function.");
        _;
    }

    /**
     * @notice Transfers ownership to the address specified.
     * @param addr Specifies the address of the new owner.
     * @dev Throws if called by any account other than the owner.
     */
    function transferOwnership (address addr) public onlyOwner {
        require(addr != address(0), "The target address cannot be the zero address");
        emit OwnershipTransferred(_owner, addr);
        _owner = addr;
    }

    /**
     * @notice Destroys the smart contract.
     * @param addr The payable address of the recipient.
     */
    function destroy(address payable addr) public virtual onlyOwner {
        require(addr != address(0), "The target address cannot be the zero address");
        require(addr != address(1), "The target address cannot be the ecrecover address");
        selfdestruct(addr);
    }

    /**
     * @notice Gets the address of the owner.
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @notice Indicates if the address specified is the owner of the resource.
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner(address addr) public view returns (bool) {
        return addr == _owner;
    }
}
/**
 * @title Represents an ownable resource.
 */
function transferOwnership (address addr) public onlyOwner {
    require(addr != address(0), "The target address cannot be the zero address");
    emit OwnershipTransferred(_owner, addr);
    _owner = addr;
}

/**
 * @notice Transfers ownership to the address specified.
 * @param addr Specifies the address of the new owner.
 * @dev Throws if called by any account other than the owner.
 */