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:
Muchas gracias
Tienes un par de errores el más notorio es declarar Car
como contrato.
TypeError: Expression has to be an lvalue.
newCar.VechileOwner = msg.sender;
^-----------------^
Aquí newCar
hay una instancia de Car
un 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 VechileOwner
es 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].deposit
es 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 Car
una estructura dentro rentCar
del 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.
En primer lugar, cuando usa el view
modificador, no puede cambiar el estado. Cualquier cambio de estado resultará en un error. view
se usa solo para llamadas estáticas. Por ejemplo, su setAvailable()
función claramente fallará ya que cambia el cars
estado 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?
ismael
Car
definición yresetRental()
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?H.Thiam
ismael
H.Thiam
ismael
*
errores con comentarios///***ERRORS
para que no causen errores de sintaxis. Comprueba si crees que algo anda mal.