Using Steem-API with Ruby Part 2 — Print Account BalancessteemCreated with Sketch.

in #utopian-io5 years ago (edited)

Steemit_Ruby.jpg

Repository

steem-ruby

radiator

What Will I Learn?

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:

  • steem-api uses closures and exceptions and provides low level computer readable data.
  • radiator uses classic function return values and provides high level human readable data.

Since both APIs have advantages and disadvantages I have provided sample code for both APIs so you can decide which is more suitable for you.

In this 2nd part you learn the use of the classes Steem::Type::Amount and Radiator::Type::Amount and how to handle account balances using them.

Requirements

You should have basic knowledge of Ruby programming you need to install at least Ruby 2.5 as well as the following ruby gems:

gem install bundler
gem install colorize
gem install steem-ruby
gem install radiator

If there is anything not clear you can ask in the comments.

Note: Both steem-ruby and radiator provide a file called steem.rb. This means that:

  1. When you install both APIs you need to tell ruby which one to use.
  2. You can't use both APIs in the same script.

Difficulty

Provided you have some programming experience this tutorial is basic level.

Tutorial Contents

In this second part of the tutorial I demonstrate how to print out account balances from a list of accounts passed on command line. The data will be formatted and a simple calculation is performed to show how you can use arithmetic on account balances.

As mentioned there will be two examples showing the differences. Both …::Amount classes have there weaknesses which I compensate by introducing an extended Amount class making the rest of the code identical.

You might notice that Steem Power is output in VESTS. In a future part I will show you how to convert VEST value into STEEM value.

Implementation using steem-ruby

Steem-ruby keeps balance data in low level structures which is rather cumbersome to use. Here an example:

  "sbd_balance"=>{"amount"=>"8716549", "precision"=>3, "nai"=>"@@000000013"},

The constructor Steem::Type::Amount class will parse the structure for you and make the data within more accessible and printable. Let's look in detail how to use Steem::Type::Amount:


Make the script executable under Unix. Of course you need to add the correct path to your ruby executable.

#!/opt/local/bin/ruby

Use the "steem.rb" file from the steem-ruby gem. This is only needed if you have both steem-api and radiator installed.

gem "steem-ruby", :require => "steem"

require 'pp'
require 'colorize'
require 'steem'

Steem-ruby comes with a helpful Steem::Type::Amoun class to handle account balances. However Steem::Type::Amoun won't let you access the actual amount as float which is quite cumbersome when you want to make calculations.

This class expands Steem::Type::Amoun to add the missing functions.

class Amount < Steem::Type::Amount

Return amount as float to be used for calculations

   def to_f
     return @amount.to_f
   end # to_f

Operator to add two balances for the users convenience

   def +(right)
      return (if right.is_a?(Numeric) then
         @amount.to_f + right
      else
         @amount.to_f + right.to_f
      end)
   end

Operator to subtract two balances for the users convenience

   def -(right)
      return (if right.is_a?(Numeric) then
         @amount.to_f - right
      else
         @amount.to_f - right.to_f
      end)
   end
end # Amount

Print account information for an array of accounts

def print_account_balances (accounts)
   accounts.each do |account|

Create an amount instances for each balance to be used for further processing

      _balance                   = Amount.new account.balance
      _savings_balance           = Amount.new account.savings_balance
      _sbd_balance               = Amount.new account.sbd_balance
      _savings_sbd_balance       = Amount.new account.savings_sbd_balance
      _vesting_shares            = Amount.new account.vesting_shares
      _delegated_vesting_shares  = Amount.new account.delegated_vesting_shares
      _received_vesting_shares   = Amount.new account.received_vesting_shares

Calculate actual vesting by adding and subtracting delegation.

      _actual_vesting            = _vesting_shares - (_delegated_vesting_shares + _received_vesting_shares)

Pretty print out the balances. Note that for a quick printout Steem::Type::Amount provides a simple to_s method. But this method won't align the decimal point

      puts ("Account: " + account.name).colorize(:blue)
      puts "  Steem           = %1$15.3f %2$s" % [_balance.to_f,                  _balance.asset]
      puts "  Steem Savings   = %1$15.3f %2$s" % [_savings_balance.to_f,          _savings_balance.asset]
      puts "  SBD             = %1$15.3f %2$s" % [_sbd_balance.to_f,              _sbd_balance.asset]
      puts "  SBD Savings     = %1$15.3f %2$s" % [_savings_sbd_balance.to_f,      _savings_sbd_balance.asset]
      puts "  Steem Power     = %1$18.6f %2$s" % [_vesting_shares.to_f,           _vesting_shares.asset]
      puts "  Delegated Steem = %1$18.6f %2$s" % [_delegated_vesting_shares.to_f, _delegated_vesting_shares.asset]
      puts "  Received Steem  = %1$18.6f %2$s" % [_received_vesting_shares.to_f,  _received_vesting_shares.asset]
      puts "  Actual Power    = %1$18.6f VESTS" % _actual_vesting
   end

   return
end # Print_Account_Balances

if ARGV.length == 0 then
   puts """
Steem-Dump-Balances — Dump account balances.

Usage:
   Steem-Dump-Balances account_name …

"""
else

Read arguments from command line

   Account_Names = ARGV

Create instance to the steem database API

   Database_Api = Steem::DatabaseApi.new

Request account information from the Steem database and print out the accounts balances found using a new function or print out error information when an error occurred.

   Database_Api.find_accounts(accounts: Account_Names) do |result|
      Accounts = result.accounts

      if Accounts.length == 0 then
         puts "No accounts found.".yellow
      else

Print out the actual account balances.

         print_account_balances Accounts
      end
   rescue => error
      puts "Error reading accounts:".red
      pp error
   end
end

Hint: Follow this link on Github for the complete script with syntax highlighting: Steem-Dump-Balances.rb on GitHub.

The output of the command (for the steem account) looks like this:

Screenshot at Jan 27 17-44-14.png

Steem-Print-Accounts.rb using radiator

Radiator keeps the amount data inside a string which nice for printing but still cumbersome for any further processing:

  "sbd_balance"=>"8716.549 SBD",

Luckily we don't need to parse the string ourself. The constructor Radiator::Type::Amount class will do that for you and provides the same functionality then Radiator::Type::Amount. Let's look in detail how to use Radiator::Type::Amount:


Make the script executable under Unix. Of course you need to add the correct path to your ruby executable.

#!/opt/local/bin/ruby

use the "steem.rb" file from the radiator gem. This is only needed if you have both steem-api and radiator installed.

gem "radiator", :require => "steem"

require 'pp'
require 'colorize'
require 'radiator'

steem-ruby comes with a helpful Radiator::Type::Amount class to handle account balances. However Radiator::Type::Amount won't let you access any attributes which makes using the class quite cumbersome.

This class expands Radiator::Type::Amount to add the missing functions making it super convenient.

class Amount < Radiator::Type::Amount

add the missing attribute reader.

   attr_reader :amount, :precision, :asset, :value

return amount as float to be used for calculations

   def to_f
     return @amount.to_f
   end # to_f

Operator to add two balances for the users convenience

   def +(right)
      return (if right.is_a?(Numeric) then
         @amount.to_f + right
      else
         @amount.to_f + right.to_f
      end)
   end

Operator to subtract two balances for the users convenience

   def -(right)
      return (if right.is_a?(Numeric) then
         @amount.to_f - right
      else
         @amount.to_f - right.to_f
      end)
   end
end # Amount

Print account information for an array of accounts

def print_account_balances (accounts)
   accounts.each do |account|

Create an amount instances for each balance to be used for further processing

      _balance                   = Amount.new account.balance
      _savings_balance           = Amount.new account.savings_balance
      _sbd_balance               = Amount.new account.sbd_balance
      _savings_sbd_balance       = Amount.new account.savings_sbd_balance
      _vesting_shares            = Amount.new account.vesting_shares
      _delegated_vesting_shares  = Amount.new account.delegated_vesting_shares
      _received_vesting_shares   = Amount.new account.received_vesting_shares

calculate actual vesting by adding and subtracting delegation.

      _actual_vesting            = _vesting_shares - (_delegated_vesting_shares + _received_vesting_shares)

Pretty print out the balances. Note that for a quick printout Radiator::Type::Amount provides a simple to_s method. But this code will create a nicer output.

      puts ("Account: " + account.name).colorize(:blue)
      puts "  Steem           = %1$15.3f %2$s" % [_balance.to_f,                  _balance.asset]
      puts "  Steem Savings   = %1$15.3f %2$s" % [_savings_balance.to_f,          _savings_balance.asset]
      puts "  SBD             = %1$15.3f %2$s" % [_sbd_balance.to_f,              _sbd_balance.asset]
      puts "  SBD Savings     = %1$15.3f %2$s" % [_savings_sbd_balance.to_f,      _savings_sbd_balance.asset]
      puts "  Steem Power     = %1$18.6f %2$s" % [_vesting_shares.to_f,           _vesting_shares.asset]
      puts "  Delegated Steem = %1$18.6f %2$s" % [_delegated_vesting_shares.to_f, _delegated_vesting_shares.asset]
      puts "  Received Steem  = %1$18.6f %2$s" % [_received_vesting_shares.to_f,  _received_vesting_shares.asset]
      puts "  Actual Power    = %1$18.6f VESTS" % _actual_vesting
   end

   return
end # Print_Account_Balances

if ARGV.length == 0 then
   puts """
Steem-Print-Balances — Print account balances.

Usage:
   Steem-Print-Balances account_name …

"""
else

Read arguments from command line

   Account_Names = ARGV

Create instance to the steem database API

   Database_Api = Radiator::DatabaseApi.new

Request account information from the Steem database and print out the accounts balances found using a new function or print out error information when an error occurred.

   Result = Database_Api.get_accounts(Account_Names)

   if Result.key?('error') then
      puts "Error reading accounts:".red
      pp Result.error
   elsif Result.result.length == 0 then
      puts "No accounts found.".yellow
   else
      print_account_balances Result.result
   end
end

Hint: Follow this link to Github for the complete script with syntax highlighting: Steem-Print-Balances.rb on GitHub.

The output of the command (for the steem account) look identical to the previous output:

Screenshot at Jan 27 17-44-59.png

Curriculum

First tutorial

Previous tutorial

Next tutorial

Proof of Work

image.png

comment votes posts level payout commented voted

Sort:  

Thank you for your contribution.

  • I loved how neatly written and commented your code is.
  • Tutorials are essentially aimed at teaching people new concepts, via sufficient explanatory textual information and visuals. I suggest you explore in upcoming tutorials writing further details within the core of your tutorial more explanation and further how-tos to help your readers grasp those concepts.
  • Your could have added a matching SP amount to the VESTS value that you extracted. For end users this is more valuable.
  • There are several tutorials for Ruby/Steem on the official developer website in here, would be great to see innovative ways to use Ruby/Steem connection in non-standard ways, somewhat aligned with some of what you tried to accomplish today.

Looking forward to future work of yours.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Your could have added a matching SP amount to the VESTS value that you extracted. For end users this is more valuable.

That's precisely what I have planned for tutorial 3. 😉 — I don't want to put too much into one tutorial.

via sufficient explanatory textual information.

The explanations are currently all in the comments. But I could beak up the code into smaller snippets and use text blocks for explanations. And I still have a few days to edit and improve.

There are several tutorials for Ruby/Steem on the official developer website in here,

I missed that one. Luckily there is no overlap yet. I'll make sure it stays that way. Also I try to make fully working examples with error handling.

Thank you for your review, @mcfarhat! Keep up the good work!

Hi @krischik!

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

Hi, @krischik!

You just got a 0.09% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.

Hey, @krischik!

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!

Coin Marketplace

STEEM 0.29
TRX 0.12
JST 0.032
BTC 63701.36
ETH 3076.90
USDT 1.00
SBD 3.81