1

I am a beginner user of solidity so I have to learn a lot. I am creating a car sales Dapp for a school assignment in remix and I can't figure out how I can keep updating an array value using user inputs. I want the possibility to update the mileage of a car wich has to be greater than the previous value using user inputs and it has to be connected to the licenseplate of a car.

At the "//" code on the bottom I get these 2 errors: TypeError: Type address is not implicitly convertible to expected type uint256. (pointing to "[msg.sender]".

TypeError: Indexed expression has to be a type, mapping or array (is struct CarApp.Car storage ref) (pointing to "cars[msg.sender]


pragma solidity >=0.8.2 <0.9.0;

contract CarApp {

    address public owner;

    struct Car {
        string licensePlate;
        string chassisNumber;
        string brand;
        string carType;
        string colour;
        uint256 mileage;
        address owner;
    }

    constructor() {
        owner = msg.sender;
    }


    Car[] public cars;

    function createCar(string memory _licensePlate, string memory _chassisNumber, string memory _brand, string memory _carType, string memory _colour) public {
        require(bytes(_licensePlate).length > 0, "Please fill in your license plate");
        require(bytes(_chassisNumber).length > 0, "Please fill in your chassis number");
        require(bytes(_brand).length > 0, "Please fill in the brand of the car");
        require(bytes(_carType).length > 0, "Please fill in the car type");
        require(bytes(_colour).length > 0, "Please fill in the colour of the car");
        cars.push (Car(_licensePlate, _chassisNumber, _brand, _carType, _colour, 0, owner));

    }

    function getCarInfo() external view returns(Car[] memory) {
        return cars;
    }


   //function addMileage(string memory _licensePlate, uint256 _mileage) public {
        //require(bytes (_licensePlate).length > 0, "Please fill in your license plate");
        //require(_mileage > cars[msg.sender][_licensePlate].mileage, "The mileage should be higher than the previous one");
        //cars[msg.sender][_licensePlate].mileage = _mileage;
    //}



}
1
  • Please accept the answer if it resolved your issue, or comment if you need any further help...
    – prc
    Mar 7 at 22:50

1 Answer 1

2

Your problem is that you are using an array, and array elements in Solidity are only addressable by their index.

You should consider a mapping if you need to address your cars by licensePlate, maybe with something like this:

contract CarApp {

    address public owner;

    struct Car {
        // string licensePlate;
        string chassisNumber;
        string brand;
        string carType;
        string colour;
        uint256 mileage;
        address owner;
    }

    constructor() {
        owner = msg.sender;
    }


    mapping(string => Car) public cars;

    function createCar(string memory _licensePlate, string memory _chassisNumber, string memory _brand, string memory _carType, string memory _colour) public {
        require(bytes(_licensePlate).length > 0, "Please fill in your license plate");
        require(bytes(_chassisNumber).length > 0, "Please fill in your chassis number");
        require(bytes(_brand).length > 0, "Please fill in the brand of the car");
        require(bytes(_carType).length > 0, "Please fill in the car type");
        require(bytes(_colour).length > 0, "Please fill in the colour of the car");
        cars[_licensePlate] = Car(_chassisNumber, _brand, _carType, _colour, 0, msg.sender);
    }

    function getCarInfo(string memory _licensePlate) external view returns(Car memory) {
        return cars[_licensePlate];
    }


   function addMileage(string memory _licensePlate, uint256 _mileage) public {
        require(bytes (_licensePlate).length > 0, "Please fill in your license plate");
        require(_mileage > cars[_licensePlate].mileage, "The mileage should be higher than the previous one");
        require(cars[_licensePlate].owner == msg.sender, "Only owner can change mileage");
        cars[_licensePlate].mileage = _mileage;
    }

}

EDIT: add more code with full change to mapping

Another example maintaining the array, and using a mapping for indexing by plates:

contract CarApp {

    address public owner;

    struct Car {
        string licensePlate;
        string chassisNumber;
        string brand;
        string carType;
        string colour;
        uint256 mileage;
        address owner;
    }

    constructor() {
        owner = msg.sender;
    }


    Car[] public cars;
    mapping (string => uint256) public plates;

    function createCar(string memory _licensePlate, string memory _chassisNumber, string memory _brand, string memory _carType, string memory _colour) public {
        require(bytes(_licensePlate).length > 0, "Please fill in your license plate");
        require(bytes(_chassisNumber).length > 0, "Please fill in your chassis number");
        require(bytes(_brand).length > 0, "Please fill in the brand of the car");
        require(bytes(_carType).length > 0, "Please fill in the car type");
        require(bytes(_colour).length > 0, "Please fill in the colour of the car");
        cars.push(Car(_licensePlate, _chassisNumber, _brand, _carType, _colour, 0, msg.sender));
        plates[_licensePlate] = cars.length - 1;
    }

    function getCarInfo() external view returns(Car[] memory) {
        return cars;
    }


   function addMileage(string memory _licensePlate, uint256 _mileage) public {
        require(bytes (_licensePlate).length > 0, "Please fill in your license plate");
        require(_mileage > cars[plates[_licensePlate]].mileage, "The mileage should be higher than the previous one");
        require(cars[plates[_licensePlate]].owner == msg.sender, "Only owner can change mileage");
        cars[plates[_licensePlate]].mileage = _mileage;
    }

}

2nd EDIT: add another example maintaining the array

8
  • First of all, thank you for your answer! When I add the mapping you send here I get another error at the "Car[] public cars;" line. The error is: "DeclarationError: Identifier already declared." And on the line for "car.push" I get this error: TypeError: Member "push" not found or not visible after argument-dependent lookup in mapping(string memory => struct CarApp.Car storage ref).
    – User122333
    Mar 7 at 20:59
  • You should use the mapping instead of the array. Also use a mapping type assignment instead of the push()... I'll add more code to make it more clear.
    – prc
    Mar 7 at 21:07
  • Thank you! I will try this. I wonder, is there a way to keep the array and maybe use someting like a for loop or an if statement or something to make it work with the array?
    – User122333
    Mar 8 at 11:30
  • Added another example maintaining the array and using a mapping for indexing by license plates. The mapping is used only for converting licensePlate to array index of the respective element. This is just an example, no optimisation has been done.
    – prc
    Mar 8 at 15:10
  • Thank you for your help! Really appreciate it!
    – User122333
    Mar 9 at 8:36

Your Answer

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

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