Skip to content

Instantly share code, notes, and snippets.

@nicksinch
Last active October 18, 2021 08:42
Show Gist options
  • Select an option

  • Save nicksinch/dd2afafe64c2c9c0aa0bf5b29fd11572 to your computer and use it in GitHub Desktop.

Select an option

Save nicksinch/dd2afafe64c2c9c0aa0bf5b29fd11572 to your computer and use it in GitHub Desktop.

Test the Smart Contract

The smart contract can be tested using Remix IDE. After compiling & deploying, an example interaction with the deployed contract looks like this:

  • Make sure account is the deployer's account
  • addBook(1, 3, "KingRat") adds 3 copies of a Book to the libraryBooks mapping with id = 3 and title = "KingRat"
  • addBook(1, 1, "KingRat") adds 1 more copy of the same book
  • addBook(2, 1, "The Bitcoin Standard") adds a new book with id=2 and title "The Bitcoin Standard"
  • libraryBooks(1) and libraryBooks(2) to see their count and title
  • since the mapping is public, everyone can easy see which books are available
  • Try switching to other account and see that only owner is allowed to add new books
  • BorrowBook(1) borrows the book with id=1, check libraryBooks(1) to see that count of "KingRat" is decreased by 1
  • BorrowBook(2) borrows book with id=2, -/-

Now, to see who borrowed which books:

  • borrowedBooks(0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c, 1) pass an address (this one is an example, you can copy a real one directly in Remix) and array index as argument and the mapping returns the book id that is borrowed
  • Since the mapping is public anyone can easily see it
  • returnBook(1) returns the book with id=1, see libraryBook(1)'s count is increased by 1
  • returnBook(2) -/-
  • returnBook(1) should revert now because the user has already returned it
  • BorrowBook(3) should revert because book with id=3 doesn't exist
pragma solidity ^0.8.0;
import "./2_Owner.sol";
contract Library is Owner { // Owner contract provided by Remix IDE by default
event bookAdded(uint id, uint count);
event borrowedBook(uint id);
event returnedBook(uint id);
struct Book {
string title;
uint count;
}
mapping(address => uint[]) public borrowedBooks;
mapping(uint => Book) public libraryBooks;
function addBook(uint _id, uint _count, string memory title) public isOwner {
require(bytes(title).length != 0, "Book's title cannot be empty");
require(_id > 0 && _count > 0, "IDs and count of books should be greater than 0 "); // we cannot have id = 0, also can't add 0 books
if(bytes(libraryBooks[_id].title).length == 0) { // only possible if the book is added for the first time
libraryBooks[_id].title = title;
}
libraryBooks[_id].count += _count;
emit bookAdded(_id, _count);
}
function borrowBook(uint id) public {
require(id > 0, "ID cannot be 0");
require(libraryBooks[id].count >= 1, "The book is not available"); // require there's at least 1 copy of the book available
uint[] memory userBooks = borrowedBooks[msg.sender];
for(uint i = 0;i<userBooks.length;i++) {
uint bookId = userBooks[i];
if(id == bookId) { // already borrowed
revert("Book is already borrowed by the user");
}
}
borrowedBooks[msg.sender].push(id); // if we are here, the book hasn't yet been borrowed
libraryBooks[id].count--;
emit borrowedBook(id);
}
function returnBook(uint id) public {
bool hasBook = false;
uint[] memory userBooks = borrowedBooks[msg.sender];
for(uint i = 0;i < userBooks.length;i++){
if(id == userBooks[i]) {
userBooks = remove(i, userBooks);
borrowedBooks[msg.sender] = userBooks;
libraryBooks[id].count++;
emit returnedBook(id);
hasBook = true;
break;
}
}
if(!hasBook) {
revert("The user doesn't have the book in order to return it!");
}
}
function remove(uint index, uint[] memory array) private pure returns(uint[] memory) {
if (index >= array.length) revert();
for (uint i = index; i<array.length-1; i++){
array[i] = array[i+1];
}
delete array[array.length-1];
//array.length--;
return array;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment