All examples from this tutorial can be found as fully functional scripts on GitHub:
This tutorial shows how to interact with the Steem blockchain and Steem database using Ruby. When using Ruby you have two APIs available to chose: steem-api and radiator which differentiates in how return values and errors are handled:
Since both APIs have advantages and disadvantages sample code for both APIs will be provided so the reader ca decide which is more suitable.
This chapter teaches how to display all up and downvotes in present on any posting. In the next part will teach how to calculate the value in SBD for each post.
Basic knowledge of Ruby programming is needed. It is necessary to install at least Ruby 2.5 as well as the following ruby gems:
gem install bundler
gem install colorize
gem install contracts
gem install steem-ruby
gem install radiator
Note: Both steem-ruby and radiator provide a file called steem.rb
. This means that:
If there is anything not clear you can ask in the comments.
For reader with programming experience this tutorial is basic level.
Information on the postings are accessed via the get_active_votes
method of the CondenserApi
. The method takes two parameter: the authors name and the id of the posting. Both can be extracted from the URL of the posting. As Result you get an array of voting results:
Name | Desciption |
---|---|
voter | Name of the voter. |
percent | percentage of vote (times 10000). |
weight | Used to calculate the vote value. |
rshares | Used to calculate the vote value. |
reputation | Voters reputation. Not used any more and always 0. |
time | Time and date of the actual vote. |
A little reminder: A % sign behind the number usually means that the number was multiplied by 100. So 1% equals 0.01 and 100% equals 1.0. Steem itself however doesn't use floating-point numbers and multiplies the percentage with 10000 instead to make them integers while still allowing for a 0.0001 / 0.01% precision.
The correct use if weight
and rshares
is rather complex and will be described in a separate tutorial.
To ease the use of the voting values we define a Value
class which does all the a parsing and converts the integer values into floating points as well as converting time stamps ti the Time
instances. Note that floating point values are not as precise but easier to use the fixed points numbers.
Class to handle vote values from postings.
class Vote < Steem::Type::BaseType
include Contracts::Core
include Contracts::Builtin
attr_reader :voter, :percent, :weight, :rshares, :reputation, :time
Create a new instance from the data returned from the get_active_votes
method. The percent is divided by 10000 to make the value mathematically correct.
Contract HashOf[String => Or[String, Num]] => nil
def initialize(value)
super(:vote, value)
@voter = value.voter
@percent = value.percent / 10000.0
@weight = value.weight
@rshares = value.rshares
@reputation = value.reputation
@time = Time.strptime(value.time + "Z" , "%Y-%m-%dT%H:%M:%S")
return
end
Create a colorised string from the instance. The vote percentages are multiplied with 100 and are colorised (positive values are printed in green, negative values in red and zero votes (yes they exist) are shown in grey), for improved human readability.
Contract None => String
def to_ansi_s
_percent = @percent * 100.0
return (
"%1$-16s : " + "%2$7.2f%%".colorize(
if _percent > 0 then
:green
elsif _percent < 0 then
:red
else
:white
end
) + "%3$12d" + "%4$15d" + "%5$20s") % [
@voter,
_percent,
@weight,
@rshares,
@time.strftime("%Y-%m-%d %H:%M:%S")]
end
Print a list a vote values:
Vote
class.print as ansi strings.
:::ruby
Contract ArrayOf[HashOf[String => Or[String, Num]] ] => nil
def self.print_list (votes)
votes.each do |vote|
_vote = Vote.new vote
puts _vote.to_ansi_s
end
return
end
Print the votes from a postings given as URLs:
Condenser_Api
using get_active_votes
print the votes.
:::ruby
Contract String => nil
def self.print_url (url)
_slug = url.split('@').last
_author, _permlink = _slug.split('/')
puts ("Post Author : " + "%1$s".blue) % _author
puts ("Post ID : " + "%1$s".blue) % _permlink
puts ("Voter name : percent weight rshares vote date & time")
Condenser_Api.get_active_votes(_author, _permlink) do |votes|
if votes.length == 0 then
puts "No votes found.".yellow
else
Vote.print_list votes
end
rescue => error
Kernel::abort(("Error reading posting “%1$s”:\n".red + "%2$s") % [_permlink, error.to_s])
end
return
end
end
To avoid replications the rest of the operation is described in the radiator chapter.
Hint: Follow this link to Github for the complete script with comments and syntax highlighting: Steem-Dump-Posting-Votes.rb.
The output of the command (for the steem account) looks like this:
To avoid replications the Vote
class is only described in the steem-ruby chapter
begin
create instance to the steem condenser API which will give us access to the active votes.
Condenser_Api = Radiator::CondenserApi.new
rescue => error
I am using Kernel::abort
so the script ends when data can't be loaded
Kernel::abort("Error reading global properties:\n".red + error.to_s)
end
Display help if no URL are given.
if ARGV.length == 0 then
puts "
Steem-Print-Posting-Votes — Print voting on account.
Usage:
Steem-Print-Posting-Votes URL …
"
else
Loop over all URLs given and print the values using the Vote class.
ARGV.each do |_url|
Vote.print_url _url
end
end
Hint: Follow this link to Github for the complete script with comments and syntax highlighting : Steem-Print-Posting-Votes.rb.
The output of the command (for the steem account) looks similar to the previous output:
This time a posting with a negative vote in red is shown.