remix – Understanding Revert with Array of Contracts

arraysremixrevert-opcode

I have the following solidity file:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

error MustBeOwner();
error BookDoesNotExist();

// book contract
contract Book {
    bool public isRegistered = false;
    string public title;
    string public author;
}

// actual library
contract Library {

    address owner;

    // all books
    Book[10] books;


    // rented books
    mapping(address => uint) rentedBooks;


    constructor() {
        owner = msg.sender;
    }


    function rentBook(uint _bookId) public view {
        if(msg.sender != owner) {
            revert MustBeOwner();
        }

        if(_bookId > books.length || books[_bookId].isRegistered()) {
            revert BookDoesNotExist();
        }
    }

}

I insert it in Ethereum Remix. It compiles successfully. I deploy it, and run function rentBook(6). A very vague error message is shown:

transact to Library.rentBook errored: VM error: revert.

revert
The transaction has been reverted to the initial state.

Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.

Best Answer

It is probably failing because the books array is empty and you're trying to access books[_bookId].isRegistered() over a non existing book. Initialize the books array with values in the Library constructor first.

Or, you can introduce a check before accessing variables such as

address(books[_bookId]) != address(0)
Related Topic