0

I am writing code for a car rental system but i'm getting a few compile error messages that don't understand.

The first error is

TypeError: Expression has to be an lvalue.

The second is

TypeError: Type address is not implicitly convertible to expected type function () view external returns (address).

The third is

TypeError: Operator < not compatible with types uint256 and function () view external returns (uint256).

Here's my code:

PLEASE NOTE: The asterisk represents which line in the code errors.

pragma solidity ^0.4.18;

contract rentCar {

    struct Renter {
        address  addr;
        uint DOB;
        uint currentRenting;
    }

    bool public rented;
    address public owner;
    uint public duration;
    uint public rentalPrice;
    uint public charge;
    uint public rentalDate;
    uint public returnDate;
    uint public rentalStartDate;
    uint public rentalEndDate;
    uint public constant totalDays = 7;


    struct NameKey{ // storage the name's keys
        uint[] keys;
    }

    //List of Cars available
    uint[] private ids;  //Use it to return the ids of Objects
    uint public numofCars;
    mapping(uint => Car) private cars;
    mapping(string => NameKey) private nameToKeys;

    //Events
    event E_addCar(uint objID, address VechileOwner);
    event E_Rent(address indexed _renter, uint _rentalDate, uint _returnDate, uint _rentalPrice);
    event E_ReturnRental(address indexed _renter, uint _returnDate);

    //Modifiers
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
    /*
    modifier onlyRenter() {
        require(msg.sender == addr);
        _;
    }
    */
    modifier whenNotRented() {
        require(!rented);
        _;
    }

    modifier whenRented() {
        require(rented);
        _;
    }

    //Funcions

    function rentCar() public{
        owner = msg.sender;
    }

    function addCar(string make, string model, uint pricePerDay, uint minRentalDay, uint maxRentalDay, bool available) public onlyOwner {

        Car newCar = cars[numofCars];
        ///nameToKeys[name].keys.push(numofCars); //add the key to the name's keys
        ///***ERRORS
        newCar.VechileOwner = msg.sender;
        newCar.make = make;
        newCar.model = model;
        newCar.available = available;
        newCar.pricePerDay = pricePerDay;
        newCar.minRentalDay = minRentalDay;
        newCar.maxRentalDay = maxRentalDay;

        newCar(numofCars,msg.sender);
        ids.push(numofCars);
        numofCars++;

    }

    function setAvailable(uint objID, bool _available) public view onlyOwner {
        ///***ERRORS
        cars[objID].available = _available;
    }

    /* function totalDays (uint rentalStartDate, uint rentalEndDate) public whenNotRented{
        uint totalDays = ;
        return totalDays;
    }*/

    function Rent(uint objID,uint totalDays) public payable  whenNotRented returns(bool){
        ///***ERRORS
        require (msg.value < cars[objID].deposit);
        require(totalDays >= cars[objID].minRentalDay && totalDays <= cars[objID].maxRentalDay);


        cars[objID].renter = Renter({addr:msg.sender, currentRenting:now});

        uint PayDeposit = msg.value - cars[objID].deposit;
        rentalPrice = totalDays *  cars[objID].pricePerDay;
        rentalDate = rentalStartDate;
        returnDate = rentalEndDate;

        cars[objID].available = false;
        rented = true;

        // accessCar();

        ///***ERRORS
        E_Rent(Renter, rentalDate, returnDate, rentalPrice);

        return true;
    }

    function endRent (uint objID, uint duration) public  whenRented {
        ///***ERRORS
        duration = (now - cars[objID].renter.currentRenting) / (24*60*60*1.0);
        charge = duration * cars[objID].priceDaily - cars[objID].deposit;
        uint totalPayment = msg.value - charge;

        require(!cars[objID].VechileOwner.send(charge));
        require(!cars[objID].renter.addr.send(charge));

        delete cars[objID].renter;
        cars[objID].available = false;

        E_ReturnRental(Renter, now);

        resetRental();
    }

    function forceRentalEnd() public onlyOwner{
        require(now > returnDate && rented);

        E_ReturnRental(Renter, now);

        resetRental();
    }

    function resetRental() private{
        rented = false;
        Renter.addr = address(0);
        rentalDate = 0;
        returnDate = 0;
    }
}

I have a second contract called Car that interacts with the other contract

contract  Car is rentCar {
    address public VechileOwner;
    string public make;
    string public model;
    Renter public renter;

    bool public available;
    uint public pricePerDay;
    uint public deposit;
    uint public entrycode;
    uint public minRentalDay;
    uint public maxRentalDay;

    function checkAvailability() public view returns (bool) {
        return(Car.available);
    }

    function Car(string _make, string _model, uint _pricePerDay, uint _minRentalDay, uint _maxRentalDay, bool _available) public onlyOwner{
        make = _make;
        model = _model;
        pricePerDay = _pricePerDay;
        minRentalDay = _minRentalDay;
        maxRentalDay = _maxRentalDay;
        available = _available;
    }  
}

I'd really appreciate the help.

Here are the error messages that appear on remix: Error messages are shown on online compilier Error messages are shown on online compilier Error messages are shown on online compilier Error messages are shown on online compilier

Many thanks

5
  • 1
    Your contract has other errors and is incomplete, it is missing Car definition and resetRental() function. Can you split your contract into smaller parts so it is easier to test and verify your error messages?
    – Ismael
    Commented Jan 25, 2018 at 16:52
  • @Ismael i have added the rest of my code.
    – H.Thiam
    Commented Jan 25, 2018 at 19:50
  • Sorry, I didn't meant to literally split the contract, but to trim the contract to a minimal example that shows the problem. I usually paste the contracts into remix.ethereum.org and check there the error messages.
    – Ismael
    Commented Jan 25, 2018 at 20:17
  • is this what you meant
    – H.Thiam
    Commented Jan 26, 2018 at 15:29
  • I've reformated your contract to make them easier to read and check for errors with remix. Also replaced the * in the errors with comments ///***ERRORS so they don't cause syntax errors. Check if you think is something is wrong.
    – Ismael
    Commented Jan 26, 2018 at 16:40

2 Answers 2

1

You have a couple of errors the most notorious is to declare Car as a contract.

TypeError: Expression has to be an lvalue.
    newCar.VechileOwner = msg.sender;
    ^-----------------^

Here newCar is an instance of Car a contract, you cannot access directly a variable of another contract.

    Car newCar = cars[numofCars];
    newCar.VechileOwner = msg.sender;

Solidity will create getters for public variables but it will not create setters you have to create them explicitely.

 TypeError: Type address is not implicitly convertible to expected type function () view external returns (address).
    newCar.VechileOwner = msg.sender;
                          ^--------^

Here the problems is that VechileOwner is the getter (a function), and you are trying to assign them an address. This is not possible.

TypeError: Operator < not compatible with types uint256 and function () view external returns (uint256)
    require (msg.value < cars[objID].deposit);
             ^-----------------------------^

A similar problem here cars[objID].deposit is a getter, and you are comparing it with an uint, it doesn't have any meaning.

IMHO a better solution is to declare Car a struct inside rentCar contract.

struct  Car {
    address VechileOwner;
    string make;
    string model;
    Renter renter;

    bool available;
    uint pricePerDay;
    uint deposit;
    uint entrycode;
    uint minRentalDay;
    uint maxRentalDay;
}

This cause other problems with the current code.

1
  • Thank you so much for taking your time to have a look at my code. Much appreciated.
    – H.Thiam
    Commented Feb 3, 2018 at 15:30
0

First of all, when you use the view modifier, you can't change the state. Any state change will result in an error. view is used for static calls only. For instance, your setAvailable() function will clearly fail since you change the cars variable state with cars[objID].available = _available;.

For the rest, I think there are some issues with your Struct calls, where is your Car struct defined?

1
  • there no struct defined, it is been called from the contract 'Car'.
    – H.Thiam
    Commented Jan 26, 2018 at 15:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.