Hive Developers logo

Hive Developer Portal

Witness Listing And Voting

Getting witnesses and voting them

Full, runnable src of Witness Listing And Voting can be downloaded as part of: tutorials/python (or download just this tutorial: devportal-master-tutorials-python-22_witness_listing_and_voting.zip).

In this tutorial we show you how to create a list of current witness votes from the Hive blockchain and then vote or unvote for a witness using the methods found within the beem library.

Intro

The beem library has a built-in function to transmit transactions to the blockchain. We are using the approvewitness and disapprovewitness method found within the account instance. We also use the WitnessesVotedByAccount module to query the blockchain for a list of voted witnesses.

Also see:

Steps

  1. App setup - Library install and import. Connection to testnet
  2. User information - Input user information
  3. Voted witness list - Create a list of witnesse already voted for
  4. Vote / Unvote - Input witness name and commite vote/unvote to blockchain

1. App setup

In this tutorial we use 3 packages:

import pprint
from pick import pick
import getpass
from beem import Hive
from beem.account import Account
from beem.witness import Witness, WitnessesVotedByAccount

Because this tutorial alters the blockchain we connect to a testnet so we don’t create spam on the production server.

2. User information

We require the private active key of the user in order for the transaction to be committed to the blockchain. This is why we are using a testnet. We also check if the user name provided is active on the chain. There are some demo accounts available but we encourage you to create your own accounts on this testnet.

# capture user information
account = input('Enter username: ')
wif_active_key = getpass.getpass('Active Key: ')

# node_url = 'https://testnet.openhive.network' # Public Testnet
node_url = 'http://127.0.0.1:8090' # Local Testnet

# connect node and private active key
client = Hive(node_url, keys=[wif_active_key])

# check valid user
account = Account(account, blockchain_instance=client)

3. Voted witness list

We provide the user with a list of witnesses that have already been voted for by their account. From this the user will know which witnesses can be removed, and which can be added to their set of approved witnesses. We generate this list using the Account module and display it on the UI.

# print list of currently voted for witnesses
print('\n' + 'WITNESSES CURRENTLY VOTED FOR')
vote_list = WitnessesVotedByAccount(account.name, blockchain_instance=client)
for witness in vote_list:
  pprint.pprint(witness.account.name)

input('Press enter to continue')

4. Vote / Unvote

The user is given the option to VOTE, UNVOTE or CANCEL the process. Depending on the choice the relevant function is executed. Both the VOTE and UNVOTE methods use the same input - the witness being added or removed. The different method executions are shown below.

# choice of action
title = ('Please choose action')
options = ['VOTE', 'UNVOTE', 'CANCEL']
# get index and selected permission choice
option, index = pick(options, title)

if (option == 'CANCEL') :
    print('\n' + 'operation cancelled')
    exit()

if (option == 'VOTE') :
    # vote process
    witness_vote = input('Please enter the witness name you wish to vote for: ')
    witness = Witness(witness_vote, blockchain_instance=client)
    if witness_vote in vote_list :
        print('\n' + witness_vote + ' cannot be voted for more than once')
        exit()
    account.approvewitness(witness_vote)
    print('\n' + witness_vote + ' has been successfully voted for')
else :
    # unvote process
    witness_unvote = input('Please enter the witness name you wish to remove the vote from: ')
    if witness_unvote not in vote_list :
        print('\n' + witness_unvote + ' is not in your voted for list')
        exit()
    account.disapprovewitness(witness_unvote)
    print('\n' + witness_unvote + ' has been removed from your voted for list')

A confirmation of the transaction to the blockchain is displayed on the UI.

Final code:

import pprint
from pick import pick
import getpass
from beem import Hive
from beem.account import Account
from beem.witness import Witness, WitnessesVotedByAccount

# capture user information
account = input('Enter username: ')
wif_active_key = getpass.getpass('Active Key: ')

# node_url = 'https://testnet.openhive.network' # Public Testnet
node_url = 'http://127.0.0.1:8090' # Local Testnet

# connect node and private active key
client = Hive(node_url, keys=[wif_active_key])

# check valid user
account = Account(account, blockchain_instance=client)

# print list of currently voted for witnesses
print('\n' + 'WITNESSES CURRENTLY VOTED FOR')
vote_list = WitnessesVotedByAccount(account.name, blockchain_instance=client)
for witness in vote_list:
  pprint.pprint(witness.account.name)

input('Press enter to continue')

# choice of action
title = ('Please choose action')
options = ['VOTE', 'UNVOTE', 'CANCEL']
# get index and selected permission choice
option, index = pick(options, title)

if (option == 'CANCEL') :
    print('\n' + 'operation cancelled')
    exit()

if (option == 'VOTE') :
    # vote process
    witness_vote = input('Please enter the witness name you wish to vote for: ')
    witness = Witness(witness_vote, blockchain_instance=client)
    if witness_vote in vote_list :
        print('\n' + witness_vote + ' cannot be voted for more than once')
        exit()
    account.approvewitness(witness_vote)
    print('\n' + witness_vote + ' has been successfully voted for')
else :
    # unvote process
    witness_unvote = input('Please enter the witness name you wish to remove the vote from: ')
    if witness_unvote not in vote_list :
        print('\n' + witness_unvote + ' is not in your voted for list')
        exit()
    account.disapprovewitness(witness_unvote)
    print('\n' + witness_unvote + ' has been removed from your voted for list')


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

  1. review dev requirements
  2. git clone https://gitlab.syncad.com/hive/devportal.git
  3. cd devportal/tutorials/python/22_witness_listing_and_voting
  4. pip install -r requirements.txt
  5. python index.py
  6. After a few moments, you should see a prompt for input in terminal screen.