contract Chargeable {

    function sendFee(uint256 kind) internal {
        sendFee(msg.sig, kind);
    }

    function sendFee(bytes4 func, uint256 kind) internal {
        address cashier = _getCashier();
        if (address(cashier) == address(0x0)) {
            return;
        }
        address payable payee = ICashier(cashier).getPayee();
        if (payee == address(0x0)) {
            return;
        }
        uint256 fee = ICashier(cashier).calcFee(address(this), kind, func);
        if (fee > 0) {
            require(address(this).balance >= fee, "Function fee is not enough.");
            payee.transfer(fee);
        }
    }

    /**
     * @dev Storage slot with the address of the cashier contract.
     * This is the keccak-256 hash of "x.cashier.contract" and is validated in the constructor.
     */
    bytes32
        internal constant _CASHIER_SLOT = 0xe4daccb11a797004e79d649410b00658e14f3296aae1b244a00c23be3d595cd4;

    function _getCashier() internal view returns (address cashier) {
        bytes32 slot = _CASHIER_SLOT;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            cashier := sload(slot)
        }
    }

    /**
     * @dev Stores a new address in the cashier slot.
     */
    function _setCashier(address addr) internal {
        bytes32 slot = _CASHIER_SLOT;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(slot, addr)
        }
    }
}
function _setCashier(address addr) internal {
    bytes32 slot = _CASHIER_SLOT;
    // solhint-disable-next-line no-inline-assembly
    assembly {
        sstore(slot, addr)
    }
}

/**
 * @dev Stores a new address in the cashier slot.
 */