fbslo cross-posted this post in HiveDevs 4 years ago


Introducing Hive Sharer - Sharing links on the chain!

in #hackathon4 years ago (edited)

Hive Sharer

Sharing links on the chain!

Website - GitHub

image.png


Abstract

Sharing links on Hive is controversial topic. Some people think that profiting from reward pool by simply sharing links is not ok, others think it should be rewarded. Post that motivated me to think about this more, was https://peakd.com/hivewatchers/@demotruk/copy-and-paste-is-not-the-same-as-spam-or-plagiarism by @demotruk.

Hive Sharer is solving this problem by introducing blockhain-based link sharing platform, where users can reward each other by tipping HIVE if they like shared content.

Users can also upvote posts (upvotes don't have any monetary value), and most upvoted posts will end up on trending page.

Reward pool is not used, users can still reward their favorite sharers and people can still share links they like. Sharers can earn only by providing high quality links (solving the problem of low quality content & self-voting).


How to use the site

You must have Hive Keychain installed to vote, comment, post or tip. Get it for Firefox or Chrome.

When you visit the site for the first time, you must enter your hive username. Your username is than stored into your browser's local storage and used with Keychain when you try to vote, comment, post... If you used wrong username, click [change username] in the footer.

To visit user's profile, click on "Account" button and enter hive username or click on author's name in the post (or click the user's avatar).

To share new link, click "Share" button, enter link, description and one tag (sorting by tag is not available yet).

This is still alpha version, there might be are still bugs in the code. Report any bugs (except "known bugs") to @fbslo. (contact & known bugs at the bottom)


How does this app works? for developers & curious cats

App is streaming blockchain and listening for custom_json operations with id hive_sharer. When they are detected, they are stored into MySQL database (for faster (offline) access, you can use HiveSQL or pure blockchain instead to build frontend for HiveSharer).

I used internal database instead of using data from blockhain because public RPC nodes can be slow and unreliable. It can also make removing unwanted content (spam...) faters, since there is no need for hardcoded blacklist, but only DELETE FROM posts WHERE author='spammer';... Data is still stored in blockchain, but frontend is not showing it anymore.

There are 3 transaction types: post, comment, vote

Frontend is accessing data using API at /api/... (more API documentation bellow.)


JSON operations

New post:

var time = new Date().getTime() //unix_timestamp * 1000
var id_post = 'fbslo' + '-' + time + '-hivesharer' //author-time-hivesharer

post = `{
  "type": "post",
  "author": "fbslo",
  "link": "https://fbslo.net",
  "description": "My personal website!",
  "time": "${time}",
  "tags": "dev",
  "id": "${id_post}"
}`

New vote:

var time = new Date().getTime()
var id_vote = 'vote-fbslo' + '-' + time + '-hivesharer'

vote = `{
  "type": "vote",
  "voter": "fbslo",
  "time": "${time}",
  "id": "${id_vote}",
  "parent_id": "fbslo-1589046191432-hivesharer"
}`

New comment:

var time = new Date().getTime()
var id_comment = 'comment-fbslo' + '-' + time + '-hivesharer'

var comment = `{
  "type": "comment",
  "author": "fbslo",
  "description": "Great Website!",
  "time": "${time}",
  "parent_id": "fbslo-1589046191432-hivesharer",
  "id": "${id_comment}"
}`

Frontend CSS templates used:

3rd party libraries used:

Frontend:

  • jQuery
  • SweetAlert2
  • Moment.js

Backend:

  • @hiveio/hive-js
  • express, body-parser, ejs
  • link-preview-node
  • mysql
  • xss

How to set up your own dApp

Clone github repository and install MySQL database.

Database schema:

  • database name: sharer
  • Tables:
Table name: posts
+---------------+---------+------+-----+---------+-------+
| Field         | Type    | Null | Key | Default | Extra |
+---------------+---------+------+-----+---------+-------+
| author        | text    | YES  |     | NULL    |       |
| link          | text    | YES  |     | NULL    |       |
| description   | text    | YES  |     | NULL    |       |
| time          | text    | YES  |     | NULL    |       |
| tags          | text    | YES  |     | NULL    |       |
| id            | text    | YES  |     | NULL    |       |
| votes         | int(11) | YES  |     | NULL    |       |
| comments      | text    | YES  |     | NULL    |       |
| image_preview | text    | YES  |     | NULL    |       |
| title_preview | text    | YES  |     | NULL    |       |
+---------------+---------+------+-----+---------+-------+

Table name: comments
+-------------+------+------+-----+---------+-------+
| Field       | Type | Null | Key | Default | Extra |
+-------------+------+------+-----+---------+-------+
| author      | text | YES  |     | NULL    |       |
| description | text | YES  |     | NULL    |       |
| time        | text | YES  |     | NULL    |       |
| parent_id   | text | YES  |     | NULL    |       |
| id          | text | YES  |     | NULL    |       |
+-------------+------+------+-----+---------+-------+

Table name: votes
+-----------+------+------+-----+---------+-------+
| Field     | Type | Null | Key | Default | Extra |
+-----------+------+------+-----+---------+-------+
| voter     | text | YES  |     | NULL    |       |
| time      | text | YES  |     | NULL    |       |
| parent_id | text | YES  |     | NULL    |       |
| id        | text | YES  |     | NULL    |       |
+-----------+------+------+-----+---------+-------+

(Instructions on how to install NodeJS, NPM and MySQL: ~~~ embed:b63bab4c9e7cfc09e5b613fbe4715937) gist metadata:ZmJzbG8vYjYzYmFiNGM5ZTdjZmMwOWU1YjYxM2ZiZTQ3MTU5Mzcp ~~~

Rename /database/db_config.json.demo to /database/db_config.json and edit your database details.

Run npm install

Run node server.js will start app on port 5000.


Trending Algorithm

To sort trending page, I used score calculated from number of votes and post age.

let score = votes / Math.pow(post_age_days, 0.6)

image.png
Example for post with 1000 votes.


API Documentation

GET /api/profile

API parameters: account (default is fbslo)

Example: /api/profile?account=fbslo

Return type: json

On error: success: false

On success:

success: true,
username: username,
name: name,
about: about,
location: location,
profile_image: profile_image,
post_count: number_of_posts_on_hive,
following: number_of_following_on_hive, //or N/A
followers: number_of_followers_on_hive //or N/A

GET /api/posts

API parameters: page (default is 1)

Limit: 10 per page

Example: /api/posts?page=2

Return type: json

On error: success: false

On Success:

[0] background_image: image_from_website,
    profile_image: author's_profile_image,
    link: webpage_link,
    author: author_username,
    id: post_id,
    title: title_from_web_page,
    description: description_by_author,
    votes: number_of_votes, //int
    comments: number_of_comments //string
...

GET /api/comments

API parameters: id

Example: /api/comments?id=fbslo-1589046191432-hivesharer

Return type: json

On error: success: false

On Success:

[0] parent_id: parent_post_id,
    author: author's_username,
    id: comment_id,
    description: comment_body,
    time: time_in_(unix_timestamp * 1000)
...

GET /api/accountposts

API parameters: account (default is fbslo)

Example: /api/accountposts?account=fbslo

Return type: json

On error: success: false

On Success:

[0] time: time_in_(unix_timestamp * 1000),
    link: website_link,
    author: author_username,
    id: post_id,
    title: title_from_web_page,
    description: description_by_author,
    votes: number_of_votes, //int
    comments: number_of_comments //string
...

GET /api/trending

API parameters: none

Example: /api/trending

Return type: json

On error: success: false

On Success:

[0] background_image: image_from_website,
    profile_image: profile_image_from_hive,
    time: time_in_(unix_timestamp * 1000),
    link: website_link,
    author: author_username,
    id: post_id,
    title: title_from_web_page,
    description: description_by_author,
    votes: number_of_votes, //int
    comments: number_of_comments //string
    trending_score: trending_score //see above explanation of trending score calculation
...


@fbslo
Discord: fbslo#8470


Known bugs:

  • Connection to RPC server fails sometimes and don't reconnect on next attempt to connect. I'm not sure if this is RPC problem, my internet connection or the code. If you submited comment, post or vote but front-end don't show it, it's probably this.
  • Poor UI responsiveness on smaller screens

This SOFTWARE PRODUCT is provided by THE PROVIDER "as is" and "with all faults." THE PROVIDER makes no representations or warranties of any kind concerning the safety, suitability, lack of viruses, inaccuracies, typographical errors, or other harmful components of this SOFTWARE PRODUCT. There are inherent dangers in the use of any software, and you are solely responsible for determining whether this SOFTWARE PRODUCT is compatible with your equipment and other software installed on your equipment. You are also solely responsible for the protection of your equipment and backup of your data, and THE PROVIDER will not be liable for any damages you may suffer in connection with using, modifying, or distributing this SOFTWARE PRODUCT.

Sort:  

Congratulations @fbslo! You have completed the following achievement on the Hive blockchain and have been rewarded with new badge(s) :

You distributed more than 55000 upvotes. Your next target is to reach 56000 upvotes.

You can view your badges on your board and compare to others on the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @hivebuzz:

Hive Revolution - Mission 1 - Communication
Hive Revolution - Call for missions
Vote for us as a witness to get one more badge and upvotes from us with more power!

Why do you down boating my posts?

Let's live in peace.

I want to stay in Hive, too.

I follow downvotes from @blocktrades