Hive Developer Portal
Vote On Content
Create a weighted up or down vote on a comment/post.
Full, runnable src of Vote On Content can be downloaded as part of: tutorials/python (or download just this tutorial: devportal-master-tutorials-python-17_vote_on_content.zip).
In this tutorial we will explain and show you how to to check if a user has voted on specified content and also how to submit a vote on the Hive blockchain using the beem library.
Intro
Voting is a way of promoting good content via an upvote
or reporting misuse, spam or other unfit content by downvoting
. The Hive python library has a built-in function to transmit transactions to the blockchain. We are using the vote
method found within the commit
class in the the library. Before we vote on content we first check whether the user has already voted. This is not strictly necessary as a voting operation overrides the previous vote value. We use the get_active_votes
function to check for this. This function only requires two parameters, the author
and the permlink
for the comment/post that the query is for. This returns a list of the current voters for that comment. The vote
function has 3 parameters:
- identifier - This is a combination of the author and permink of the post/comment that the vote will be on
- weight - This value determines whether the vote is an upvote (+100.0), a downvote (-100.0), or zero (0) to remove previous vote.
- username - The name of the account that is executing the vote
Also see:
Steps
- App setup - Library install and import. Connection to testnet
- User information - Input user information and connection to Hive node
- Check vote status - Vote status of post/comment
- Commit vote - Commit vote to the blockchain
1. App setup
In this tutorial we use 3 packages:
beem
- hive library and interaction with Blockchainpick
- helps select the query type interactively
We import the libraries and connect to the testnet
.
from pick import pick
import getpass
from beem import Hive
from beem.account import Account
from beem.vote import ActiveVotes
from beem.transactionbuilder import TransactionBuilder
from beembase.operations import Vote
Because this tutorial alters the blockchain we connect to the testnet so we don’t create spam on the production server.
2. User information
We also require the private posting key
of the user that wishes to vote on the selected content so the action can be committed to the blockchain. This is why we have to specify this along with the testnet
node. The values are supplied via the terminal/console before we initialise the beem class. We have supplied a test account, cdemo
to use with this tutorial but any account set up on the testnet can be used.
# capture user information
voter = input('Please enter your username (voter): ')
# connect node
# If using mainnet, try with demo account: cdemo, posting key: 5JEZ1EiUjFKfsKP32b15Y7jybjvHQPhnvCYZ9BW62H1LDUnMvHz
# client = Hive('https://testnet.openhive.network') # Public Testnet
client = Hive('http://127.0.0.1:8090') # Local Testnet
3. Check vote status
In order to give the user an educated choice we first check whether they have already voted on the given post/comment. The author and permlink for the post is supplied via the console/terminal.
# capture variables
author = input('Author of post/comment that you wish to vote for: ')
permlink = input('Permlink of the post/comment you wish to vote for: ')
The vote status check is done with a simple query to the blockchain.
# check vote status
# noinspection PyInterpreter
print('checking vote status - getting current post votes')
identifier = ('@' + author + '/' + permlink)
author_account = Account(author, blockchain_instance=client)
result = ActiveVotes(identifier, blockchain_instance=client)
print(len(result), ' votes retrieved')
This query returns a list of the current voters on the specified post/comment. The result is checked against the username to determine what the current status is.
if result:
for vote in result :
if vote['voter'] == voter:
title = "This post/comment has already been voted for"
break
else:
title = "No vote for this post/comment has been submitted"
else:
title = "No vote for this post/comment has been submitted"
4. Commit vote
The result from the previous step is used to give the user a choice in what the next step in the operation should be.
# option to continue
options = ['Add/Change vote', 'Cancel without voting']
option, index = pick(options, title)
The user is given a choice to either continue with the vote or cancel the operation. If the user elects to continue, the vote
function is executed. The weight of the vote is input from the UI and the identifier parameter is created by combining the author and permlink values.
if option == 'Add/Change vote':
weight = input('\n' + 'Please advise weight of vote between -100.0 and 100 (zero removes previous vote): ')
try:
tx = TransactionBuilder(blockchain_instance=client)
tx.appendOps(Vote(**{
"voter": voter,
"author": author,
"permlink": permlink,
"weight": int(float(weight) * 100)
}))
wif_posting_key = getpass.getpass('Posting Key: ')
tx.appendWif(wif_posting_key)
signed_tx = tx.sign()
broadcast_tx = tx.broadcast(trx_id=True)
print("Vote cast successfully: " + str(broadcast_tx))
except Exception as e:
print('\n' + str(e) + '\nException encountered. Unable to vote')
else:
print('Voting has been cancelled')
When the function is executed the selected vote weight overrides any value previously recorded on the blockchain.
A simple confirmation of the chosen action is printed on the screen.
Final code:
from pick import pick
import getpass
from beem import Hive
from beem.account import Account
from beem.vote import ActiveVotes
from beem.transactionbuilder import TransactionBuilder
from beembase.operations import Vote
# capture user information
voter = input('Please enter your username (voter): ')
# connect node
# If using mainnet, try with demo account: cdemo, posting key: 5JEZ1EiUjFKfsKP32b15Y7jybjvHQPhnvCYZ9BW62H1LDUnMvHz
# client = Hive('https://testnet.openhive.network') # Public Testnet
client = Hive('http://127.0.0.1:8090') # Local Testnet
# capture variables
author = input('Author of post/comment that you wish to vote for: ')
permlink = input('Permlink of the post/comment you wish to vote for: ')
# check vote status
# noinspection PyInterpreter
print('checking vote status - getting current post votes')
identifier = ('@' + author + '/' + permlink)
author_account = Account(author, blockchain_instance=client)
result = ActiveVotes(identifier, blockchain_instance=client)
print(len(result), ' votes retrieved')
if result:
for vote in result :
if vote['voter'] == voter:
title = "This post/comment has already been voted for"
break
else:
title = "No vote for this post/comment has been submitted"
else:
title = "No vote for this post/comment has been submitted"
# option to continue
options = ['Add/Change vote', 'Cancel without voting']
option, index = pick(options, title)
if option == 'Add/Change vote':
weight = input('\n' + 'Please advise weight of vote between -100.0 and 100 (zero removes previous vote): ')
try:
tx = TransactionBuilder(blockchain_instance=client)
tx.appendOps(Vote(**{
"voter": voter,
"author": author,
"permlink": permlink,
"weight": int(float(weight) * 100)
}))
wif_posting_key = getpass.getpass('Posting Key: ')
tx.appendWif(wif_posting_key)
signed_tx = tx.sign()
broadcast_tx = tx.broadcast(trx_id=True)
print("Vote cast successfully: " + str(broadcast_tx))
except Exception as e:
print('\n' + str(e) + '\nException encountered. Unable to vote')
else:
print('Voting has been cancelled')
To Run the tutorial
You can launch a local testnet, with port 8090 mapped locally to the docker container:
docker run -d -p 8090:8090 inertia/tintoy:latest
For details on running a local testnet, see: Setting Up a Testnet
- review dev requirements
git clone https://gitlab.syncad.com/hive/devportal.git
cd devportal/tutorials/python/17_vote_on_content
pip install -r requirements.txt
python index.py
- After a few moments, you should see a prompt for input in terminal screen.