Beginner
How to create a Dapp On Tron Network
In this tutorial, we will be learning how to create a decentralized application (DApp) on the Tron network. We will be building a decentralized library that allows users to borrow, browse, and add books. We will be using TronLink’s Chrome extension and Node.js for this tutorial. We will be defining the data structure for our DApp and implementing functions such as adding a book, borrowing a book, and deleting a book from the library. We will also be defining events for our DApp to track new rentals and deleted books. Finally, we will be deploying our DApp on the Tron network and testing its functionality.
Install
Nodej v10+
Shell
# node -v v10.24.1
TronLink
Install Tronlink’s Chrome extension.
What Are We Doing
We are building a decentralized library that contains the following functions:
-
Book borrowing
-
Book browsing
-
Book adding
Download the complete project code from here, and run npm install to install dependencies.
Data Structure
Typically, borrowers are concerned with the title, content, availability, and price of the book. On this basis, we design a structure in the contract called Book, which comprises the following properties:
solidity
struct Book { string name; string description; bool valid; // false if been borrowed uint256 price; // TRX per day address owner; // owner of the book }
We hope that the library will be able to have an easy way to find every book. To do this, we build a bookId attribute and a mapping relationship between bookId and Book, named books.
solidity
uint256 public bookId; mapping (uint256 => Book) public books;
Additionally, we must keep track of each book’s rental information, including the borrower and the start and end dates.
As with Book, construct a structure called Tracking to keep track of this data. This structure possesses the following fields:
solidity
struct Tracking { uint256 bookId; uint256 startTime; // start time, in timestamp uint256 endTime; // end time, in timestamp address borrower; // borrower's address }
Similarly, a mapping relationship must be established to manage each rental record:
solidity
uint256 public trackingId; mapping(uint256 => Tracking) public trackings;
Functions and Events
We are adding fundamental functions to our library, including:
- Add a book to the library – addBook
- Borrow a book – borrowBook
- Remove a book from the library – deleteBook
addBook
solidity
/** * @dev Add a Book with predefined `name`, `description` and `price` * to the library. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {NewBook} event. */ function addBook(string memory name, string memory description, uint256 price) public returns (bool) { Book memory book = Book(name, description, true, price, _msgSender()); books[bookId] = book; emit NewBook(bookId++); return true; } /** * @dev Emitted when a new book is added to the library. * Note bookId starts from 0. */ event NewBook(uint256 bookId);
borrowBook
solidity
/** * @dev Borrow a book has `_bookId`. The rental period starts from * `startTime` ends with `endTime`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `NewRental` event. */ function borrowBook(uint256 _bookId, uint256 startTime, uint256 endTime) public payable returns(bool) { Book storage book = books[_bookId]; require(book.valid == true, "The book is currently on loan"); require(_msgValue() == book.price * _days(startTime, endTime), "Incorrect fund sent."); _sendTRX(book.owner, _msgValue()); _createTracking(_bookId, startTime, endTime); emit NewRental(_bookId, trackingId++); }
deleteBook
solidity
/** * @dev Delete a book from the library. Only the book's owner or the * library's owner is authorised for this operation. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `DeleteBook` event. */ function deleteBook(uint256 _bookId) public returns(bool) { require(_msgSender() == books[_bookId].owner || isOwner(), "You are not authorised to delete this book."); delete books[_bookId]; emit DeleteBook(_bookId); return true; }
We use two tool methods in the borrowBook method: _sendTRX and _createTracking. We do not wish for users to invoke these APIs. As a result, in accordance with Solidity’s standards, we identify them as internal, which means they can be accessed only within the contract.
_sendTRX
solidity
/** * @dev Send TRX to the book's owner. */ function _sendTRX(address receiver, uint256 value) internal { payable(address(uint160(receiver))).transfer(value); }
_createTracking
solidity
/** * @dev Create a new rental tracking. */ function _createTracking(uint256 _bookId, uint256 startTime, uint256 endTime) internal { trackings[trackingId] = Tracking(_bookId, startTime, endTime, _msgSender()); Book storage book = books[_bookId]; book.valid = false; }
The contract is done, it’s time to deploy it.