Error de compilación del sistema de alquiler de coches

Estoy escribiendo código para un sistema de alquiler de coches, pero recibo algunos mensajes de error de compilación que no entiendo.

El primer error es

TypeError: la expresión tiene que ser un lvalue.

el segundo es

TypeError: la dirección de tipo no se puede convertir implícitamente a la función de tipo esperada () ver devoluciones externas (dirección).

el tercero es

TypeError: Operador < no compatible con tipos uint256 y función () ver retornos externos (uint256).

Aquí está mi código:

TENGA EN CUENTA: El asterisco representa qué línea en los errores de código.

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;
    }
}

Tengo un segundo contrato llamado Car que interactúa con el otro contrato

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;
    }  
}

Realmente apreciaría la ayuda.

Estos son los mensajes de error que aparecen en el remix:Los mensajes de error se muestran en el compilador en línea Los mensajes de error se muestran en el compilador en línea Los mensajes de error se muestran en el compilador en línea Los mensajes de error se muestran en el compilador en línea

Muchas gracias

Su contrato tiene otros errores y está incompleto, le falta Cardefinición y resetRental()función. ¿Puede dividir su contrato en partes más pequeñas para que sea más fácil probar y verificar sus mensajes de error?
@Ismael, he agregado el resto de mi código.
Lo siento, no quise dividir literalmente el contrato, sino recortar el contrato a un ejemplo mínimo que muestre el problema. Normalmente pego los contratos en remix.ethereum.org y reviso allí los mensajes de error.
¿es esto lo que quisiste decir?
He reformateado su contrato para que sea más fácil de leer y comprobar si hay errores con remix. También reemplazó los *errores con comentarios ///***ERRORSpara que no causen errores de sintaxis. Comprueba si crees que algo anda mal.

Respuestas (2)

Tienes un par de errores el más notorio es declarar Carcomo contrato.

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

Aquí newCarhay una instancia de Carun contrato, no puede acceder directamente a una variable de otro contrato.

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

Solidity creará getters para variables públicas pero no creará setters, debe crearlos explícitamente.

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

Aquí el problema es que VechileOwneres el captador (una función), y está tratando de asignarles una dirección. Esto no es posible.

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

Un problema similar aquí cars[objID].deposites un getter, y lo estás comparando con un uint, no tiene ningún significado.

En mi humilde opinión, una mejor solución es declarar Caruna estructura dentro rentCardel contrato.

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

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

Esto causa otros problemas con el código actual.

Muchas gracias por tomarse su tiempo para echar un vistazo a mi código. Muy apreciado.

En primer lugar, cuando usa el viewmodificador, no puede cambiar el estado. Cualquier cambio de estado resultará en un error. viewse usa solo para llamadas estáticas. Por ejemplo, su setAvailable()función claramente fallará ya que cambia el carsestado de la variable con cars[objID].available = _available;.

Por lo demás, creo que hay algunos problemas con sus llamadas a Struct, ¿dónde está definida su estructura Car?

no hay una estructura definida, se llama desde el contrato 'Car'.