Loading...
// 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;
}
}
// 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.
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.
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.
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.
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.
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.
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.
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
.
Click here to access the smart contracts repo, I will be adding more contracts frequently