Repository
https://github.com/artolabs/steemax
SteemAX is an auto upvote exchange program that lets Steemians swap votes with each other for an agreed upon length of time.
SteemAX 1.1 Released
First I'd like to give much thanks to @outwork who has once again stepped up and delivered excellent quality work in response to my task request for a new homepage for SteemAX. This is the first of many task requests I plan on creating in the upcoming weeks as SteemAX needs help with the creation, revamping and redesigning of certain pages and functions. I'm just a meek back-end programmer with an idea and I could use help from visionary designers and graphics experts like @outwork. Thank you!
In this new release from SteemAX, version 1.1 provides an optimized vote exchange algorithm aimed at a faster run-time and that's less consuming of resources. This will be a continual endeavor throughout all future releases. New functionality has been added as well. A page that shows the history of all exchanges was created to show details about the time, post identifiers, and vote values traded in each exchange. This can be displayed as a list of all exchanges on SteemAX, or a list of all exchanges for a particular account.
Some Of The Benefits Of Using SteemAX
- Better relations with your fellow Steemians.
- A mechanism for supporting minnows long-term.
- A better way for whales to distribute upvotes.
- An avenue for minnows to seek support without feeling like they have their hand out.
- A way of socializing the current platform away from pure capitalism...
- But also a true "open market" where upvotes can be traded and bartered upon.
- Since Steemians can trade their vote at disproportional ratios, they can seek profits above and beyond what self voting could achieve, thus eliminating the temptation to over self vote.
- Whales that exchange at ratios favorable to minnows stand a better chance of receiving curation rewards, plus a substantial return on the value of their vote.
- To use SteemAX is free since no fees are taken and all SBD used to start and accept invites goes directly to the other party.
SteemAX Benefits The Whole System
Because whales are unable to manually distribute their upvote consistently, bid bots were created. SteemAX is a much better solution for distributing upvotes automatically than a bid bot:
Because the number of blocks processed by witnesses is perhaps as equally important as the "distribution of wealth" on the Steemit platform, bid bots were created to provide both. SteemAX solves this problem by still maintaining a high number of transactions, but via an exchange, from voter to voter, rather than centrally distributed by a bid bot.
Because each exchange must be manually agreed upon, the likely-hood of upvotes going to human created content rather than spam is greatly increased, as people are much more likely to agree to things they support.
Exchanges Have Been Running Smoothly
The first users of SteemAX have already created a number of exchanges which have commenced since my last post. Each exchange has occurred automatically without any problems, and it appears that transactions are at least scalable beyond what they are currently running at by several factors. Of course, I anticipate the need for optimization will arrive quickly. As a step towards a faster algorithm, I've reduced the need for SteemAX to renew access tokens to only when they expire. I accomplished this by refactoring the methods vote_on_it
and renew_token
and by creating a new method which, for lack of imagination, I named sc_vote
, which actually initializes SteemConnect and makes the vote. vote_on_it
checks if sc_vote
fails and if so uses renew_token
to use the refresh token to gain a new access token and save it to the database, then tries sc_vote
to make a vote again.
def vote_on_it(self, voter, author, post, weight):
""" Use the tokens in the database to vote on
a post. If the vote fails, renews the token
and tries again.
"""
db = axdb.AXdb(default.dbuser,
default.dbpass,
default.dbname)
if db.get_user_token(voter) is not False:
accesstoken = db.dbresults[0][1]
refreshtoken = db.dbresults[0][2]
else:
return False
# If the vote fails then we renew the token
if not self.sc_vote(voter, author, post, weight, accesstoken):
print("Renewing token for " + voter)
newtoken = self.renew_token(voter, refreshtoken)
if newtoken is not False:
return self.sc_vote(voter, author, post, weight, newtoken)
else:
self.msg.error_message("A NEW TOKEN COULD NOT BE CREATED")
return False
def sc_vote(self, voter, author, post, weight, token):
""" Takes the given token and initializes SteemConnect
to make a vote. Analyzes the result and prints the
outcome to screen as well as returns a boolean result.
"""
self.steem.connect.sc = None
self.steem.connect.steemconnect(
token)
result = self.steem.connect.vote(
voter,
author,
post,
int(weight))
try:
result['error']
# We use a broad exception clause to "catch" everything
# that is not an error
except:
# The vote was successful
print(str(voter) + " has voted on "
+ str(post) + " "
+ str(weight) + "%")
return True
else:
self.msg.error_message(str(result))
return False
def renew_token(self, accountname, refreshtoken):
""" If the access token has expired
use the refresh token to get a new access token.
"""
if self.steem.verify_key(
acctname="", tokenkey=refreshtoken):
db.update_token(self.steem.username,
self.steem.accesstoken,
self.steem.refreshtoken)
return self.steem.accesstoken
else:
return False
The commit for these changes also includes some PEP 8 inspired adjustments of whitespace and triple double quotes for the doc strings.
New Feature: Exchange History
SteemAX now has a public page that displays a history of all exchanges that have taken place between its users. The history details the two parties involved in the exchange (inviter vs. invitee), the amount exchanged ($0.10 vs. $0.10), the date and time the exchange took place, and the respective blog posts that were upvoted, which can be seen by placing the cursor over the account names.
This page has been placed at the address:
https://SteemAX.info/history
Or see an individual account history by visiting
https://SteemAX.info/history/@accountname
Please do not judge the web page design because layout and design are not my primary skills. It's my intention to create a task request to hand over the actual design of this page (plus a few others) to someone with more skill than myself. My goal was to create the back-end functionality and have a front-end that demonstrates that functionality.
Steps Taken
These new features were accomplished by creating a new table in the database that records all the archived exchanges and their pertinent information. A method was also created for inserting an exchange into the database.
if not self.get_results("SELECT * FROM axhistory WHERE 1;"):
self.commit('CREATE TABLE IF NOT EXISTS axhistory '
+ '(ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, '
+ 'MemoID varchar(100), '
+ 'Account1 varchar(200), Account2 varchar(200), '
+ 'VoteValue1 varchar(100), VoteValue2 varchar(100), '
+ 'Identifier1 varchar(400), Identifier2 varchar(400), '
+ 'Time TIMESTAMP NOT NULL '
+ 'DEFAULT CURRENT_TIMESTAMP '
+ 'ON UPDATE CURRENT_TIMESTAMP);')
def archive_exchange(self, memoid, account1, account2,
ident1, ident2, vote1, vote2):
""" If posts and votes are eligible and
an exchange occurs it is recorded in the
database.
"""
return self.commit('INSERT INTO axhistory (MemoID, Account1, '
+ 'Account2, VoteValue1, VoteValue2, Identifier1, Identifier2) '
+ 'VALUES (%s, %s, %s, %s, %s, %s, %s);',
memoid, account1, account2, vote1, vote2, ident1, ident2)
I also created a method for retrieving archived exchanges for all of steemax or just an individual account.
def get_exchange_archive(self, account=None):
""" Returns a list of all the recent exchanges
that have occured on steemax
"""
if account is None:
if self.get_results('SELECT Account1, Account2, VoteValue1, '
+ 'VoteValue2, Identifier1, Identifier2, Time '
+ 'FROM axhistory WHERE 1 ORDER BY Time DESC;'):
return self.dbresults
else:
if self.get_results('SELECT Account1, Account2, VoteValue1, '
+ 'VoteValue2, Identifier1, Identifier2, Time '
+ 'FROM axhistory WHERE %s IN (Account1, Account2) '
+ 'ORDER BY Time DESC;',
str(account)):
return self.dbresults
The commit for this code also contains a change to the archive_exchange
method and a slight change to the size of the table columns.
Next, the code in steemax.py
was created that is necessary for displaying the list of archived exchanges on the command line, both for easy access as well as testing prior to going live on the website.
def do_exchanges(self, args):
""" Lists all the archived exchanges for an account
"""
account = input("Account (press enter for none): ")
# If no account is entered return the whole list
if not account or account == "" or account == 0:
account = None
else:
print ("Looking up " + account)
axlist = db.get_exchange_archive(account)
for trade in axlist:
print(str(trade[6]))
print("@" + str(trade[0]) + "/" + str(trade[2])
+ "\nvs.\n" + "@" + str(trade[1]) + "/" + str(trade[3]))
print(str(trade[4]) + " vs. " + str(trade[5]) + "\n\n")
Obviously the command line list is for administrator use so a method was created for displaying the list as a web page. It simply gets the list of archived exchanges from the database, then using the load_template
and make_page
methods generates and returns an HTML page of the list.
def archive_page(self, account=None):
""" Provides a list of all the exchanges that
have occurred for a particular account. if
no account is provided then a list of all exchanges
for all accounts is returned.
"""
infobox = ""
if account is not None:
account = sec.filter_account(account)
# If the token is invalid return user to the login page
if not self.db.get_user_token(account):
return self.auth_url()
axlist = self.db.get_exchange_archive(account)
boxtemplate = self.load_template("templates/archivebox.html")
for trade in axlist:
date = (str(trade[6].hour) + ":"
+ str(trade[6].minute) + " "
+ str(trade[6].strftime("%B")) + " "
+ str(trade[6].day) + ", "
+ str(trade[6].year) + " ")
box = self.make_page(boxtemplate,
TIMESTAMP=date,
ACCOUNT1=trade[0],
ACCOUNT2=trade[1],
IDENT1=trade[2],
IDENT2=trade[3],
VOTEVALUE1=trade[4],
VOTEVALUE2=trade[5])
infobox = infobox + box
pagetemplate = self.load_template("templates/archive.html")
# If the account was provide we display it with the @
# however if it's not we convert it to an empty string
# so that it is not displayed in HTML
if account is None:
account = ""
else:
account = "@" + account
return ("\r\n" + self.make_page(pagetemplate,
ACCOUNT=account,
INFOBOX=infobox))
This commit also contains some minor refactoring to better conform to PEP 8 standards.
Finally, the HTML and CSS were created for the history page as well as the Python script that executes the 'archive_page` on the server.
#!/usr/bin/python3
from cgi import FieldStorage
from steemax.web import Web
account = FieldStorage().getvalue('account')
print ("Content-type: text/html")
print (Web().archive_page(account))
Commit #1 for HTML
Commit #2 for HTML
Commit #3 for HTML
Commit #4 for CSS
Commit #5 for Python
Technology Stack
SteemAX is written to use Python 3.5 and MySQL. The web interface for https://steemax.trade and https://steemax.info has been written in HTML, CSS and Javascript.
Roadmap
In the future more contributors will be brought into the fold
via Task Requests to help improve the functionality of the site and most especially the look and feel. After all, projects always benefit from the synergistic action of teamwork.
Contact
Please contact Mike (Mike-A) on Discord
https://discord.gg/97GKVFC
Thank you for you kind words @learnelectronics! Feel fre to reach me out when you need my help!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
You bet!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Thank you learnelectronics! You've just received an upvote of 61% by @ArtTurtle!
@ArtTurtle Wants To Upvote Your Art & Music!
The quickest and easiest way to start receiving an upvote for each and every single one of your art and music posts is by delegating 20 SP or more to @ArtTurtle using this delegate button. It's fully automatic and once your delegation has hit the blockchain @ArtTurtle will begin upvoting your art and music content within 45 minutes.
Don't want to give up your SP? You can also get @ArtTurtle's upvotes by signing up for free to Artopium.com! For more detailed information about @ArtTurtle and how it works be sure to check out this recent article by @Artopium titled @ArtTurtle Will Upvote Each & Every One of Your Art/Music Posts
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Upvoted.
DISCLAIMER: Your post is upvoted based on curation algorithm configured to find good articles e.g. stories, arts, photography, health, etc. This is to reward you (authors) for sharing good content using the Steem platform especially newbies.
If you're a dolphin or whales, and wish not to be included in future selection, please let me know so I can exclude your account. And if you find the upvoted post is inappropriate, FLAG if you must. This will help a better selection of post.
Keep steeming good content.
@Yehey
Posted using https://Steeming.com condenser site.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Hi @learnelectronics!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @learnelectronics! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Award for the number of upvotes
Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word
STOP
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Hey, @learnelectronics!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit