-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlibraryrent.sol
70 lines (56 loc) · 1.87 KB
/
libraryrent.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
pragma solidity ^0.8.0;
contract Library {
struct Book {
string name;
string author;
uint stock;
}
struct Rent {
bool now;
bool ever;
}
Book[] private books;
address public owner;
mapping (uint => address[]) public everRentingUsers;
mapping (uint => mapping (address => Rent)) public rents;
modifier onlyOwner() {
require(owner == msg.sender, 'CALLER_IS_NOT_OWNER');
_;
}
modifier onlyExistingBook(uint id) {
require(id < books.length, 'BOOK_DOES_NOT_EXIST');
_;
}
event BookAdded(uint indexed id, string name, string author, uint stock);
event BookBorrowed(uint indexed id, address indexed user);
event BookReturned(uint indexed id, address indexed user);
constructor() {
owner = msg.sender;
}
function addBook(string memory name, string memory author, uint stock) external onlyOwner returns(uint id) {
require(stock > 0, 'STOCK_ZERO');
id = books.length;
books.push(Book(name, author, stock));
emit BookAdded(id, name, author, stock);
}
function borrowBook(uint id) external onlyExistingBook(id) {
Book storage book = books[id];
require(book.stock > 0, 'NO_AVAILABLE_COPIES');
Rent storage rent = rents[id][msg.sender];
require(!rent.now, 'USER_ALREADY_RENTED_BOOK');
book.stock--;
rent.now = true;
emit BookBorrowed(id, msg.sender);
if (!rent.ever) {
rent.ever = true;
everRentingUsers[id].push(msg.sender);
}
}
function returnBook(uint id) external onlyExistingBook(id) {
Rent storage rent = rents[id][msg.sender];
require(rent.now, 'USER_HAS_NOT_RENTED_BOOK');
books[id].stock++;
rent.now = false;
emit BookReturned(id, msg.sender);
}
}