0

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.

3
  • Where is defined MustBeOwner() and BookDoesNotExist() ?
    – n1c01a5
    Jan 15, 2022 at 19:07
  • @n1c01a5 lines 5-6 Jan 15, 2022 at 19:07
  • Yep sorry I was not aware with this new type error. BTW if you call it with another acc than msg.sender it's normal to have this message : ` The transaction has been reverted to the initial state.`
    – n1c01a5
    Jan 15, 2022 at 19:10

1 Answer 1

3

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)
3
  • 1
    The arrays has fixed length Book[10] so it will never be empty, the rest is true it is not initialized so every element is the zero address.
    – Ismael
    Jan 15, 2022 at 19:28
  • Thanks! Why do I have to cast the element to address 0 if it's of type "Book" ? The initial value of a fixed array having type other than primitive ones is set to address 0? Jan 15, 2022 at 22:18
  • What @razgraf wants to say that Book is not a struct, but a contract. If you do not intialize it, it will point to the address 0. When you know call isRegistered on that address it will not return anything. Solidity checks if the returned value is a valid boolean, but since nothing is returned this checks fails and therefore you get this cryptic revert (as it fails on a low level check).
    – Richard
    Jan 15, 2022 at 22:30

Your Answer

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

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