0

new to ethereum. I'm tring to write smartcontracto to manage car rental. Can anyone explain me why the function to insert new car is not working (code below):

function insertnewcar(string memory model, string memory plate_) public  {
    car[c].car_name = model;
      car[c].plate = plate;
      car[c].car_id += 1;
     c++;
}

I make it work only putting the function in this way:

      function insertnewcar(string memory model, string memory plate_) public  {
        
         /* car[c].car_name = model;
          car[c].plate = plate;
          car[c].car_id += 1;
         c++; */
         
         
         car.push(Car({
             car_name:model,
             plate:plate_,
             car_id:c+1
         }));
     
     c++;
  }

I leave you below the entire code. the error i'm getting is "invalid opcode. invalid opcode the execution might have thrown. debug the transaction to get more information."

thanks!

pragma solidity ^0.6.0;

contract new_client {
    enum carstatus {free, rented, maintenance}
    struct Car {
        string car_name;
        string plate;
        uint car_id;
    }
    
    mapping(address => Car) booking;
    Car[] public car;
     uint c=0;
    
    struct Client {
        string name;
        string surname;
        uint age;
        bool license;
        address id;
    
    }
    
    uint total_client;
    
    Client[] public client;
    uint numberofclient;
    
    function innewclient(string memory name_, string memory surname_, uint  age_, bool  license_, address id_) public  {
        require(age_ >= 18, "must be 18 at least");
        require(age_ <= 75, "can't be over 75");
        
        client.push(Client({
            name: name_,
            surname: surname_,
            age: age_,
            license: license_,
            id: id_
            
        }));
        
        numberofclient = client.length;
        
    }
                                
   function gettotalclient() public view  returns(uint) {
        
       return numberofclient;
   }
    
    function checkifclient(address _id) public view returns(bool,uint) {
        for (uint i=0; i<=numberofclient;i++ ) {
            if (client[i].id ==_id){
                return (true,i);
        }
        else {
            return (false,0);
        }
    }
    
  }
  
  function insertnewcar(string memory model, string memory plate_) public  {
    
     /* car[c].car_name = model;
      car[c].plate = plate;
      car[c].car_id += 1;
     c++; */
     
     
     car.push(Car({
         car_name:model,
         plate:plate_,
         car_id:c+1
     }));
     
     c++;
  }
  
  function gettotalcar() public view returns(uint) {
      return car.length;
  }
  
  
  function carlist() public view returns(string memory,string memory,uint) {
      
      for (uint i=0; i<=car.length; i++){
          
          return (car[i].car_name,car[i].plate,car[i].car_id);
      }
  }
}


 
1

You have corrected it.

The problem was you cannot access a non-existent element of an array.

So, so given c = 0, and car.length = 0 you cannot access the first non-existent row of the array which is numbered 0. If row 0 existed, then the array length would be 1. When you try car[0] on an empty array, you get an error because you are out of bounds.

So, your correction is the right approach.

You don't actually need c or c++ because this is being done for you in car.length.

You can save additional storage by noticing that car.car_id is always the array index + 1. Even better, just use the array index as the de facto car_id and save gas by not storing it explicitly. You already have Car[] public car; which gives you a "free" getter function that returns a car at an index. Approximately:

function car(uint index) public view returns(string memory car_name, string memory plate) {
  return(car[index].car_name, car[index].plate);
}

Someone using that function can go out of bounds, and that will error out, but they are asking for a non-existent car so it's probably the right thing to do. And, there's no excuse for it because you kindly make the array length discoverable. No properly function system should walk off the end of the array.

So, it makes sense to just determine that car ids start at 0 and declare victory.

Hope it helps.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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