Skip to content

Instantly share code, notes, and snippets.

@inertia186
Last active February 26, 2018 21:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save inertia186/3107372d2a52fed7c8f1a2e943cf6300 to your computer and use it in GitHub Desktop.
Save inertia186/3107372d2a52fed7c8f1a2e943cf6300 to your computer and use it in GitHub Desktop.
This is the Gator delegation script for STEEM. Please have a look at the README.md file.
  • Title: gator.rb - STEEM Power Delegation script for STEEM
  • Tags: radiator ruby steem steemdev delegation
  • Notes:

Changes

Mostly a compatibility/code update for the latest version of #radiator and other gems.

Overview

Gator allows you to delegate STEEM Power from one account to another. This script is especially useful for dealing with multiple delegator accounts, like mined accounts.

Please note, this script is intended for doing delegation from a large number of accounts in a single batch. If you would like to delegate from a single account, you should consider Vessel by @jesta.


Install

To use this Radiator script:

Linux
$ sudo apt-get install ruby-full git openssl libssl1.0.0 libssl-dev
$ gem install bundler
macOS
$ gem install bundler

I've tested it on various versions of ruby. The oldest one I got it to work was:

ruby 2.0.0p645 (2015-04-13 revision 50299) [x86_64-darwin14.4.0]

First, clone this gist and install the dependencies:

$ git clone https://gist.github.com/3107372d2a52fed7c8f1a2e943cf6300.git gator
$ cd gator
$ bundle install

Edit the file delegators.txt and add all of the accounts you want to delegate from. You must use the active-wif.


Upgrade

Typically, you can upgrade to the latest version by this command, from the original directory you cloned into:

$ git pull

Usually, this works fine as long as you haven't modified anything. If you get an error, try this:

$ git stash --all
$ git pull --rebase
$ git stash pop

If you're still having problems, I suggest starting a new clone.


Usage

To do the actual delegation:

$ ruby gator.rb vesting_shares:42437.7 delegatee:inertia broadcast:true

Gator will now delegate 42437.700000 VESTS to inertia (for example).

To delegate a dynamic amount based on the current vesting balance of each delegator:

$ ruby gator.rb vesting_shares:auto delegatee:inertia broadcast:true

Gator will now delegate 100% of vesting - 1 STEEM to inertia. It is advisable to leave some VESTS on the account, otherwise it won't have enough bandwidth to do anything.

To reset delegation:

$ ruby gator.rb vesting_shares:0 delegatee:inertia broadcast:true

Gator will now remove all delegation for each delegator from inertia. Keep in mind, when resetting delegation, any amount that was previously delegated will be in limbo and take 7 days to return to the original delegator.


Check here to see an updated version of this script:

https://gist.github.com/inertia186/3107372d2a52fed7c8f1a2e943cf6300


Troubleshooting

Problem: What does this error mean?
gator.yml:1: syntax error, unexpected ':', expecting end-of-input
Solution: You ran ruby gator.yml but you should run ruby gator.rb.

![](http://i.imgur.com/FBoXX3w.png)

See my previous Ruby How To posts in: /f/ruby

Get in touch!

If you're using Gator, I'd love to hear from you. Drop me a line and tell me what you think! I'm @inertia on STEEM and SteemSpeak.

License

I don't believe in intellectual "property". If you do, consider Gator as licensed under a Creative Commons CC0 License.

account-name your-active-wif-here
require 'rubygems'
require 'bundler/setup'
require 'yaml'
Bundler.require
DELEGATORS_PATH = 'delegators.txt'
CONFIG_PATH = __FILE__.sub(/\.rb$/, '.yml')
@config = YAML.load_file(CONFIG_PATH)
@config[:chain_options][:chain] = @config[:chain_options][:chain].to_sym
@config[:chain_options][:logger] = Logger.new(__FILE__.sub(/\.rb$/, '.log'))
@vest_asset, @core_asset = case @config[:chain_options][:chain]
when :steem then ['VESTS', 'STEEM']
when :golos then ['GESTS', 'GOLOS']
when :test then ['CESTS', 'CORE']
else; raise "Unsupported chain: #{@config[:chain_options][:chain]}"
end
ARGV.each do |arg|
if arg =~ /vesting_shares:.+/
@vesting_shares = arg.split('vesting_shares:').last
unless @vesting_shares == 'auto'
@vesting_shares = ("%.6f #{@vest_asset}" % @vesting_shares.to_f) rescue nil
end
end
if arg =~ /delegatee:.+/
@delegatee = arg.split('delegatee:').last rescue nil
end
if arg =~ /broadcast:.+/
@broadcast = arg.split('broadcast:').last.to_s.downcase == 'true' rescue false
end
end
if @vesting_shares.nil? || @delegatee.nil?
puts "Usage:"
puts "\truby #{__FILE__} vesting_shares:<amount> delegatee:<account> broadcast:true"
puts "\nvesting_shares amount can either be a positive #{@vest_asset} value or auto. Setting auto will delgate 100 % - 1 #{@core_asset}."
exit
end
raise "Not found: #{DELEGATORS_PATH}" unless File.exist? DELEGATORS_PATH
@delegators = {}
File.open(DELEGATORS_PATH).read.each_line do |pair|
key, value = pair.split(' ')
@delegators[key] = value if !!key
end
raise "File empty: delegators.txt" if @delegators.empty?
unless File.exist? CONFIG_PATH
puts "Unable to find: #{@config_path}"
exit
end
pluralized_delegators = if @delegators.size == 1
"1 delegator"
else
"#{@delegators.size} delegators"
end
if @broadcast
puts "Now delegating #{@vesting_shares} to #{@delegatee} from #{pluralized_delegators} ..."
else
puts "Dry run: NOT delegating #{@vesting_shares} to #{@delegatee} from #{pluralized_delegators} ..."
end
sleep 10 # Give them time to chang thir mind.
@success = false
@api = Radiator::Api.new(@config[:chain_options])
@core_per_vest = ((1 / @api.steem_per_mvest) * 1000000).round(6)
if @vesting_shares == 'auto'
@api.get_accounts(@delegators.keys) do |delegator_accounts, error|
if !!error
puts error
exit
end
@accounts = {}
delegator_accounts.each do |account|
vests = account.vesting_shares.split(' ').first.to_f
delegated_vests = account.delegated_vesting_shares.split(' ').first.to_f
vests = vests - delegated_vests - @core_per_vest
@accounts[account.name] = "%.6f #{@vest_asset}" % vests
end
end
end
@delegators.each do |delegator, wif|
begin
amount = if @vesting_shares == 'auto'
if @accounts[delegator].to_f < @core_per_vest
puts "Skipping #{delegator}. Not enough #{@vest_asset}."
next
end
@accounts[delegator]
else
@vesting_shares
end
puts "#{delegator} delegating #{amount} to #{@delegatee}"
tx = Radiator::Transaction.new(@config[:chain_options].merge(wif: wif))
tx.operations << {
type: :delegate_vesting_shares,
delegator: delegator,
delegatee: @delegatee,
vesting_shares: amount
}
response = tx.process(@broadcast)
if defined?(response.error) && !!response.error
message = response.error.message
if message =~ /Missing Active Authority/
puts "Unable to delegate from #{delegator} to #{@delegatee}. Check active wif."
exit
elsif message =~ /You cannot delegate #{@vest_asset} to yourself/
puts "Unable to delegate from #{delegator} to #{@delegatee}. You cannot delegate to yourself."
elsif message =~ /Delegation must be removed or leave minimum delegation amount of/
msg = message.split("\n")[1].split(': ').last
puts "Unable to delegate from #{delegator} to #{@delegatee}: #{msg}"
elsif message =~ /increase is not enough of a different. min_update:/
msg = message.split("\n")[1].split(': ')[1..-1].join(': ')
puts "Unable to delegate from #{delegator} to #{@delegatee}: #{msg}"
elsif message =~ /Delegation cannot be negative/
puts "Unable to delegate from #{delegator} to #{@delegatee}. Delegation cannot be negative."
else
raise response.error.message
end
end
puts "\tSuccess: #{response.result.to_json}" if defined?(response.result)
@success = true
rescue => e
puts "Unable to delegate from #{delegator} to #{@delegatee}: #{e}"
end
end
if @success && !@broadcast
puts "\nUsage:"
puts "\truby #{__FILE__} vesting_shares:#{@vesting_shares} delegatee:#{@delegatee} broadcast:true"
exit
end
:chain_options:
:chain: steem
:url: https://api.steemit.com
source 'https://rubygems.org'
gem 'radiator'
GEM
remote: https://rubygems.org/
specs:
awesome_print (1.8.0)
bitcoin-ruby (0.0.13)
connection_pool (2.2.1)
ffi (1.9.18)
hashie (3.5.6)
json (2.1.0)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
multi_json (1.12.2)
net-http-persistent (3.0.0)
connection_pool (~> 2.2)
radiator (0.3.15)
awesome_print (~> 1.7, >= 1.7.0)
bitcoin-ruby (~> 0.0, >= 0.0.11)
ffi (~> 1.9, >= 1.9.18)
hashie (~> 3.5, >= 3.5.5)
json (~> 2.0, >= 2.0.2)
logging (~> 2.2, >= 2.2.0)
net-http-persistent (>= 2.5.2)
PLATFORMS
ruby
DEPENDENCIES
radiator
BUNDLED WITH
1.16.0.pre.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment