# Create Library Management Smart Contract

## Library Management Smart contract

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;
contract Library {
    constructor() {
        
    }
    struct Book {
        // this struct will store the details of the book
        uint256 id;
        string name;
        string author;
        uint256 year;
        bool isFinished;
    }
    
    Book[] private books;
    
    mapping(uint256 =>address) public bookToOwner; 
// this mapping will map the book id to the owner address


    event AddBook( address, uint);


    function addBook(string memory _name, string memory _author, uint256 _year,bool finished) external {
        //  this function will add a book to the library
        books.push(Book(books.length, _name, _author, _year,finished));
        bookToOwner[books.length-1] = msg.sender;
        emit AddBook(msg.sender, books.length-1);
    }
    
    function _getBooks(bool finished) private view returns(Book[] memory) {
        //  this function will return all the books in the library
        Book[] memory result = new Book[](books.length);
        uint256 counter = 0;
        for(uint256 i = 0; i < books.length; i++) {
            if(books[i].isFinished == finished && bookToOwner[i] == msg.sender) {
                result[counter] = books[i];
                counter++;
            }
        }
        Book[] memory result2 = new Book[](counter);
        for(uint256 i = 0; i < counter; i++) {
            result2[i] = result[i];
        }
        return result2;
    }

    function getUnfinishedBooks() external view returns(Book[] memory) {
        //  this function will return all the books in the library which are not finished   
        return _getBooks(false);
    }

    function getFinishedBooks() external view returns(Book[] memory) {
        // this function will return all the books in the library which are finished
        return _getBooks(true);
    }


    function setFinished( uint bookId, bool finished ) external {
        // this function will set the finished status of a book
        require(bookId < books.length, "Book does not exist");
        require(bookToOwner[bookId] == msg.sender, "You are not the owner of this book");
        books[bookId].isFinished = finished;
    }
        
}
```

## Smart Contract Explanation and Breakdown

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;
contract Library {
    constructor() {
        
    }
```

* `// SPDX-License-Identifier: UNLICENSED`: This is a comment in the Solidity code that specifies the license under which the code is released.
    
* `pragma solidity 0.8.17;`: This statement specifies the version of the Solidity compiler to use when compiling the contract. In this case, it specifies the version `0.8.17`.
    
* `contract Library {`: This declares a new Solidity contract called `Library`.
    
* `constructor() {`: This is the constructor function of the contract. Since it's empty, it doesn't do anything when the contract is deployed.
    
* `}`: This closes the constructor function.
    
* `}`: This closes the contract.
    

```solidity
 struct Book {
        // this struct will store the details of the book
        uint256 id;
        string name;
        string author;
        uint256 year;
        bool isFinished;
    }
```

* `struct Book {`: This declares a new custom data type called `Book` as a struct.
    
* `// this struct will store the details of the book`: This is a comment that describes the purpose of the `Book` struct.
    
* `uint256 id;`: This declares an unsigned integer variable called `id` to store the book ID.
    
* `string name;`: This declares a string variable called `name` to store the book title.
    
* `string author;`: This declares a string variable called `author` to store the name of the book author.
    
* `uint256 year;`: This declares an unsigned integer variable called `year` to store the publication year of the book.
    
* `bool isFinished;`: This declares a boolean variable called `isFinished` to store whether the book has been finished or not.
    
* `}`: This closes the `Book` struct definition.
    

```solidity
    Book[] private books;
    
    mapping(uint256 =>address) public bookToOwner; 
// this mapping will map the book id to the owner address


    event AddBook( address, uint);
```

* `Book[] private books;`: This declares a private dynamic array of `Book` structs called `books`. This array will store all the books added to the library.
    
* `mapping(uint256 =>address) public bookToOwner;`: This declares a public mapping called `bookToOwner` that maps a book ID (represented as a `uint256`) to the address of the person who added the book to the library. This is used to keep track of who owns which book.
    
* `// this mapping will map the book id to the owner address`: This is a comment that describes the purpose of the `bookToOwner` mapping.
    
* `event AddBook( address, uint);`: This declares a new event called `AddBook` that takes in two arguments: an address (representing the person who added the book) and a `uint` (representing the book ID). This event will be emitted every time a new book is added to the library, and can be used by external contracts to monitor changes to the library.
    

```solidity
    function addBook(string memory _name, string memory _author, uint256 _year,bool finished) external {
        //  this function will add a book to the library
        books.push(Book(books.length, _name, _author, _year,finished));
        bookToOwner[books.length-1] = msg.sender;
        emit AddBook(msg.sender, books.length-1);
    }
```

* `function addBook(string memory _name, string memory _author, uint256 _year,bool finished) external {`: This declares a function called `addBook` that takes in four arguments: `_name` (a string representing the name of the book), `_author` (a string representing the name of the book's author), `_year` (an unsigned integer representing the year the book was published), and `finished` (a boolean value representing whether or not the book has been finished).
    
* `// this function will add a book to the library`: This is a comment that describes the purpose of the `addBook` function.
    
* `books.push(Book(books.length, _name, _author, _year,finished));`: This line creates a new `Book` struct with the given parameters and adds it to the end of the `books` array. The `books.length` parameter represents the ID of the book (since IDs start at 0 and are assigned sequentially as books are added to the library), and `finished` represents whether or not the book has been finished. The other parameters represent the name of the book, the author of the book, and the year the book was published.
    
* `bookToOwner[books.length-1] = msg.sender;`: This line sets the value of the `bookToOwner` mapping for the new book to the address of the person who added the book (which is stored in `msg.sender`).
    
* `emit AddBook(msg.sender, books.length-1);`: This line emits an `AddBook` event with two arguments: `msg.sender` (representing the address of the person who added the book) and `books.length-1` (representing the ID of the new book). This allows external contracts to monitor changes to the library.
    

```solidity
 function _getBooks(bool finished) private view returns(Book[] memory) {
        //  this function will return all the books in the library
        Book[] memory result = new Book[](books.length);
        uint256 counter = 0;
        for(uint256 i = 0; i < books.length; i++) {
            if(books[i].isFinished == finished && bookToOwner[i] == msg.sender) {
                result[counter] = books[i];
                counter++;
            }
        }
        Book[] memory result2 = new Book[](counter);
        for(uint256 i = 0; i < counter; i++) {
            result2[i] = result[i];
        }
        return result2;
    }
```

* `_getBooks` is a private function, meaning that it can only be called within the contract and not from outside.
    
* The function takes a boolean parameter named `finished`, which indicates whether to return the books that are finished or unfinished.
    
* The function creates a new dynamic array of `Book` structures named `result` with a length equal to the length of the `books` array.
    
* A counter variable named `counter` is initialized to 0.
    
* A loop is started that iterates through all the books in the `books` array and checks if the book is finished and is owned by the caller (the `msg.sender`).
    
* If the book satisfies the above conditions, it is added to the `result` array at the index specified by the `counter` variable and the `counter` is incremented.
    
* After the loop ends, a new dynamic array of `Book` structures named `result2` is created with a length equal to `counter`.
    
* Another loop is started that iterates through the first `counter` elements of the `result` array and copies them into the `result2` array.
    
* Finally, the function returns the `result2` array that contains only the books that satisfy the specified conditions.
    

```solidity
   function getUnfinishedBooks() external view returns(Book[] memory) {
        //  this function will return all the books in the library which are not finished   
        return _getBooks(false);
    }
```

This part of the code defines a function named `getUnfinishedBooks` that:

* Is publicly accessible (with `external` modifier).
    
* Returns an array of `Book` structs wrapped in a dynamic memory array.
    
* Calls the `_getBooks` function with the parameter `false` which retrieves books that are not finished.
    
* Returns the array of books retrieved from `_getBooks`.
    
* Does not modify any state variables.
    

Therefore, this function allows anyone to view the books in the library that are not finished, without modifying the state of the contract.

```solidity
    function getFinishedBooks() external view returns(Book[] memory) {
        // this function will return all the books in the library which are finished
        return _getBooks(true);
    }
```

This code defines a function called `getFinishedBooks` which has the following properties:

* It is a public function that can be called from outside the contract.
    
* It takes no arguments.
    
* It returns an array of `Book` structs.
    
* It uses the `view` modifier, which indicates that the function will not modify the state of the contract.
    
* The function calls the private `_getBooks` function with the argument `true`.
    
* `_getBooks` is a helper function that returns an array of `Book` structs which are either finished or unfinished based on the value of the `finished` parameter.
    
* The `true` argument passed to `_getBooks` indicates that only books which are marked as finished will be returned.
    
* The function returns an array of `Book` structs containing all books in the library that are marked as finished.
    

```solidity
    function setFinished( uint bookId, bool finished ) external {
        // this function will set the finished status of a book
        require(bookId < books.length, "Book does not exist");
        require(bookToOwner[bookId] == msg.sender, "You are not the owner of this book");
        books[bookId].isFinished = finished;
    }
        
}
```

* The `setFinished` function sets the `isFinished` status of a book identified by `bookId` to `finished`.
    
* The function takes two parameters: `bookId` of type `uint` and `finished` of type `bool`.
    
* The function is defined as `external`, which means that it can be called from outside the contract by other contracts or user wallets.
    
* The `require` statements enforce two conditions that must be met before the function can execute successfully. If either of these conditions is false, the function will revert and any changes made will be reverted as well:
    
    * `bookId < books.length` ensures that the book exists in the `books` array.
        
    * `bookToOwner[bookId] == msg.sender` ensures that the caller of the function is the owner of the book.
        
* If the conditions are met, the `isFinished` property of the book at the specified `bookId` is set to the value of `finished`.
    

## Github Code

[Click here to access the smart contracts repo, I will be adding more contracts frequently](https://github.com/moayaan1911/smart-contracts)
