class SteemTransfer: def __init__(self, account): self.account = SteemAccount(account) self.transfers = None self.se_wallet = Wallet(self.account.author) def get_token_transfers(self, token, offset=0, limit=100): if self.transfers is None: url = URL.format(account=self.account.author, symbol=token, offset=offset, limit=limit) try: r = requests.get(url) if r.ok: self.transfers = r.json() else: logger.error("Failed when retrieving transfer info") except: logger.error( "Failed when retrieving transfer info. Error: {}".format( traceback.format_exc())) return self.transfers def transfer(self, to, token, amount, memo="", retries=5): if retries <= 0: logger.info("Transfer failed after maximum retires") return if to and token and amount and memo is not None: token = token.upper() try: if token in ["STEEM", "SBD"]: self.account.account.transfer(to, amount, token, memo) else: self.se_wallet.transfer(to, amount, token, memo=memo) logger.info("Transferred {} {} to {} with memo [{}]".format( amount, token, to, memo)) except: logger.error( "Failed when tranferring {} {} to {} with memo [{}].\nError: {}" .format(amount, token, to, memo, traceback.format_exc())) self.transfer(to, token, amount, memo, retries - 1)
def transfer(to, amount, token, memo, account): """Transfer a token""" stm = shared_steem_instance() if stm.rpc is not None: stm.rpc.rpcconnect() if not account: account = stm.config["default_account"] if not bool(memo): memo = '' if not unlock_wallet(stm): return wallet = Wallet(account, steem_instance=stm) tx = wallet.transfer(to, amount, token, memo) tx = json.dumps(tx, indent=4) print(tx)
from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import sys from datetime import datetime, timedelta import time import io import logging from beem import Steem from steemengine.wallet import Wallet from beembase import transactions, operations log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) if __name__ == "__main__": stm = Steem() stm.wallet.unlock(pwd="wallet_pass") wallet = Wallet("beembot", steem_instance=stm) dragon_token = wallet.get_token("DRAGON") if dragon_token is not None and float(dragon_token["balance"]) >= 0.01: print("balance %.2f" % float(dragon_token["balance"])) print(wallet.transfer("holger80", 0.01, "DRAGON", "test")) else: print("Could not sent") time.sleep(15) wallet.refresh() dragon_token = wallet.get_token("DRAGON") print("new balance %.2f" % float(dragon_token["balance"]))
for h in history: if int(h["block"]) <= last_steem_block: continue if h["to"] != upvote_account: continue last_steem_block = int(h["block"]) if len(whitelist) > 0 and h["from"] not in whitelist: print("%s is not in the whitelist, skipping" % h["from"]) continue if len(blacklist) > 0 and h["from"] in blacklist: print("blacklisted user, skipping...") continue if float(h["quantity"]) < kitten_ratio: print("Below min token amount skipping...") print( wallet.transfer(h["from"], float(h["quantity"]), "KITTENS", "Refund - Below minimum!")) print("refund sent") continue if float(h["quantity"]) % 20: print("incorrect ratio, skipping...") print( wallet.transfer( h["from"], float(h["quantity"]), "KITTENS", "Refund - Amount must be a multiple of the current ratio!" )) print("refund sent...") continue if main_token is not None and float(main_token["balance"]) >= 1: print("balance %.2f" % float(main_token["balance"])) print( wallet.transfer(h["from"],
def run(self, start_block): self.stm.wallet.unlock(self.config["wallet_password"]) self.blockchain = Blockchain(mode='head', steem_instance=self.stm) stop_block = self.blockchain.get_current_block_num() if start_block is not None: last_block_num = start_block - 1 self.log_data["start_block_num"] = start_block for op in self.blockchain.stream(start=start_block, stop=stop_block, opNames=["comment"], max_batch_size=50): self.log_data = print_block_log(self.log_data, op, self.config["print_log_at_block"]) last_block_num = op["block_num"] if op["type"] == "comment": token = None for key in self.token_config: if op["body"].find( self.token_config[key]["comment_command"]) >= 0: token = key if token is None: continue if op["author"] == self.token_config[token]["token_account"]: continue try: c_comment = Comment(op, steem_instance=self.stm) c_comment.refresh() except: logger.warn("Could not read %s/%s" % (op["author"], op["permlink"])) continue if c_comment.is_main_post(): continue if abs((c_comment["created"] - op['timestamp']).total_seconds()) > 9.0: logger.warn("Skip %s, as edited" % c_comment["authorperm"]) continue already_replied = False for r in c_comment.get_all_replies(): if r["author"] == self.token_config[token][ "token_account"]: already_replied = True if already_replied: continue muting_acc = Account(self.token_config[token]["token_account"], steem_instance=self.stm) blocked_accounts = muting_acc.get_mutings() if c_comment["author"] in blocked_accounts: logger.info("%s is blocked" % c_comment["author"]) continue # Load bot token balance bot_wallet = Wallet(self.token_config[token]["token_account"], steem_instance=self.stm) symbol = bot_wallet.get_token( self.token_config[token]["symbol"]) # parse amount when user_can_specify_amount is true amount = self.token_config[token]["default_amount"] if self.token_config[token]["user_can_specify_amount"]: start_index = c_comment["body"].find( self.token_config[token]["comment_command"]) stop_index = c_comment["body"][start_index:].find("\n") if stop_index >= 0: command = c_comment["body"][start_index + 1:start_index + stop_index] else: command = c_comment["body"][start_index + 1:] command_args = command.replace(' ', ' ').split(" ")[1:] if len(command_args) > 0: try: amount = float(command_args[0]) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split( exc_tb.tb_frame.f_code.co_filename)[1] logger.warn("%s - %s - %s" % (str(exc_type), str(fname), str(exc_tb.tb_lineno))) logger.info("Could not parse amount") if self.token_config[token][ "maximum_amount_per_comment"] and amount > self.token_config[ token]["maximum_amount_per_comment"]: amount = self.token_config[token][ "maximum_amount_per_comment"] if not self.config["no_broadcast"] and self.stm.wallet.locked( ): self.stm.wallet.unlock(self.config["wallet_password"]) self.log_data["new_commands"] += 1 wallet = Wallet(c_comment["author"], steem_instance=self.stm) token_in_wallet = wallet.get_token( self.token_config[token]["symbol"]) if token_in_wallet is not None: balance = float(token_in_wallet["balance"]) if "stake" in token_in_wallet: balance += float(token_in_wallet['stake']) if 'delegationsIn' in token_in_wallet and float( token_in_wallet['delegationsIn']) > 0: balance += float(token_in_wallet['delegationsIn']) if 'pendingUnstake' in token_in_wallet and float( token_in_wallet['pendingUnstake']) > 0: balance += float(token_in_wallet['pendingUnstake']) if balance > self.token_config[token][ "min_token_in_wallet"]: if self.token_config[token][ "token_in_wallet_for_each_outgoing_token"] > 0: max_token_to_give = int( balance / self.token_config[token] ["token_in_wallet_for_each_outgoing_token"]) else: max_token_to_give = self.token_config[token][ "maximum_amount_per_comment"] else: max_token_to_give = 0 else: max_token_to_give = 0 db_data = read_data(self.data_file) if "accounts" in db_data and c_comment["author"] in db_data[ "accounts"] and token in db_data["accounts"][ c_comment["author"]]: if db_data["accounts"][c_comment["author"]][token][ "last_date"] == date.today( ) and self.token_config[token][ "token_in_wallet_for_each_outgoing_token"] > 0: max_token_to_give = max_token_to_give - db_data[ "accounts"][c_comment["author"]][token]["amount"] if amount > max_token_to_give: amount = max_token_to_give if amount > self.token_config[token][ "maximum_amount_per_comment"]: amount = self.token_config[token][ "maximum_amount_per_comment"] if token_in_wallet is None or float( token_in_wallet["balance"] ) < self.token_config[token]["min_token_in_wallet"]: reply_body = self.token_config[token]["fail_reply_body"] elif max_token_to_give < 1: reply_body = self.token_config[token][ "no_token_left_for_today"] elif c_comment["parent_author"] == c_comment["author"]: reply_body = "You cannot sent token to yourself." elif float(symbol["balance"]) < amount: reply_body = self.token_config[token]["no_token_left_body"] else: if "{}" in self.token_config[token]["sucess_reply_body"]: reply_body = (self.token_config[token] ["sucess_reply_body"]).format( c_comment["parent_author"]) else: reply_body = self.token_config[token][ "sucess_reply_body"] if "{}" in self.token_config[token]["token_memo"]: token_memo = ( self.token_config[token]["token_memo"]).format( c_comment["author"]) else: token_memo = self.token_config[token]["token_memo"] sendwallet = Wallet( self.token_config[token]["token_account"], steem_instance=self.stm) try: logger.info( "Sending %.2f %s to %s" % (amount, self.token_config[token]["symbol"], c_comment["parent_author"])) sendwallet.transfer(c_comment["parent_author"], amount, self.token_config[token]["symbol"], token_memo) if "accounts" in db_data: accounts = db_data["accounts"] else: accounts = {} if c_comment["author"] not in accounts: accounts[c_comment["author"]] = {} accounts[c_comment["author"]][token] = { "last_date": date.today(), "n_comments": 1, "amount": amount } elif token not in accounts[c_comment["author"]]: accounts[c_comment["author"]][token] = { "last_date": date.today(), "n_comments": 1, "amount": amount } else: if accounts[c_comment["author"]][token][ "last_date"] < date.today(): accounts[c_comment["author"]][token] = { "last_date": date.today(), "n_comments": 1, "amount": amount } else: accounts[c_comment["author"]][token][ "n_comments"] += 1 accounts[c_comment["author"]][token][ "amount"] += amount store_data(self.data_file, "accounts", accounts) logger.info( "%s - %s" % (c_comment["author"], str(accounts[c_comment["author"]][token]))) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split( exc_tb.tb_frame.f_code.co_filename)[1] logger.warn( "%s - %s - %s" % (str(exc_type), str(fname), str(exc_tb.tb_lineno))) logger.warn("Could not send %s token" % self.token_config[token]["symbol"]) continue reply_identifier = construct_authorperm( c_comment["parent_author"], c_comment["parent_permlink"]) if self.config["no_broadcast"]: logger.info("%s" % reply_body) else: try: self.stm.post( "", reply_body, author=self.token_config[token]["token_account"], reply_identifier=reply_identifier) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split( exc_tb.tb_frame.f_code.co_filename)[1] logger.warn( "%s - %s - %s" % (str(exc_type), str(fname), str(exc_tb.tb_lineno))) logger.warn("Could not reply to post") continue if self.token_config[token]["usage_upvote_percentage"] > 0: try: c_comment.upvote(self.token_config[token] ["usage_upvote_percentage"], voter=self.token_config[token] ["token_account"]) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split( exc_tb.tb_frame.f_code.co_filename)[1] logger.warn("%s - %s - %s" % (str(exc_type), str(fname), str(exc_tb.tb_lineno))) logger.warn("Could not upvote comment") time.sleep(4) return last_block_num
def run(self, start_block): self.stm.wallet.unlock(self.config["wallet_password"]) self.blockchain = Blockchain(mode='head', steem_instance=self.stm) stop_block = self.blockchain.get_current_block_num() if start_block is not None: last_block_num = start_block - 1 self.log_data["start_block_num"] = start_block for op in self.blockchain.stream(start=start_block, stop=stop_block, opNames=["comment"], max_batch_size=50): self.log_data = print_block_log(self.log_data, op, self.config["print_log_at_block"]) last_block_num = op["block_num"] if op["type"] == "comment": token = None for key in self.token_config: if op["body"].find(self.token_config[key]["comment_command"]) >= 0: token = key if token is None: continue if op["author"] == self.token_config[token]["scot_account"]: continue try: c_comment = Comment(op, steem_instance=self.stm) c_comment.refresh() except: logger.warn("Could not read %s/%s" % (op["author"], op["permlink"])) continue if c_comment.is_main_post(): continue if abs((c_comment["created"] - op['timestamp']).total_seconds()) > 9.0: logger.warn("Skip %s, as edited" % c_comment["authorperm"]) continue already_replied = False for r in c_comment.get_all_replies(): if r["author"] == self.token_config[token]["scot_account"]: already_replied = True if already_replied: continue # Load scot token balance scot_wallet = Wallet(self.token_config[token]["scot_account"], steem_instance=self.stm) scot_token = scot_wallet.get_token(self.token_config[token]["scot_token"]) # parse amount when user_can_specify_amount is true amount = self.token_config[token]["maximum_amount"] if self.token_config[token]["user_can_specify_amount"]: start_index = c_comment["body"].find(self.token_config[token]["comment_command"]) stop_index = c_comment["body"][start_index:].find("\n") if stop_index >= 0: command = c_comment["body"][start_index + 1:start_index + stop_index] else: command = c_comment["body"][start_index + 1:] command_args = command.replace(' ', ' ').split(" ")[1:] if len(command_args) > 0: try: amount = float(command_args[0]) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] logger.warn("%s - %s - %s" % (str(exc_type), str(fname), str(exc_tb.tb_lineno))) logger.info("Could not parse amount") if not self.config["no_broadcast"] and self.stm.wallet.locked(): self.stm.wallet.unlock(self.config["wallet_password"]) self.log_data["new_commands"] += 1 wallet = Wallet(c_comment["author"], steem_instance=self.stm) token_in_wallet = wallet.get_token(self.token_config[token]["scot_token"]) if token_in_wallet is None or float(token_in_wallet["balance"]) < self.token_config[token]["min_staked_token"]: reply_body = self.token_config[token]["fail_reply_body"] elif c_comment["parent_author"] == c_comment["author"]: reply_body = "You cannot sent token to yourself." elif float(scot_token["balance"]) < amount: reply_body = self.token_config[token]["no_token_left_body"] else: if "%s" in self.token_config[token]["sucess_reply_body"]: reply_body = self.token_config[token]["sucess_reply_body"] % c_comment["parent_author"] else: reply_body = self.token_config[token]["sucess_reply_body"] if "%s" in self.token_config[token]["token_memo"]: token_memo = self.token_config[token]["token_memo"] % c_comment["author"] else: token_memo = self.token_config[token]["token_memo"] sendwallet = Wallet(self.token_config[token]["scot_account"], steem_instance=self.stm) try: logger.info("Sending %.2f %s to %s" % (amount, self.token_config[token]["scot_token"], c_comment["parent_author"])) sendwallet.transfer(c_comment["parent_author"], amount, self.token_config[token]["scot_token"], token_memo) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] logger.warn("%s - %s - %s" % (str(exc_type), str(fname), str(exc_tb.tb_lineno))) logger.warn("Could not send %s token" % self.token_config[token]["scot_token"]) continue reply_identifier = construct_authorperm(c_comment["parent_author"], c_comment["parent_permlink"]) if self.config["no_broadcast"]: logger.info("%s" % reply_body) else: try: self.stm.post("", reply_body, author=self.token_config[token]["scot_account"], reply_identifier=reply_identifier) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] logger.warn("%s - %s - %s" % (str(exc_type), str(fname), str(exc_tb.tb_lineno))) logger.warn("Could not reply to post") continue if self.token_config[token]["usage_upvote_percentage"] > 0: try: c_comment.upvote(self.token_config[token]["usage_upvote_percentage"], voter=self.token_config[token]["scot_account"]) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] logger.warn("%s - %s - %s" % (str(exc_type), str(fname), str(exc_tb.tb_lineno))) logger.warn("Could not upvote comment") time.sleep(4) return last_block_num
class Scot: def __init__(self, config, steemd_instance): self.config = config self.stm = steemd_instance self.daily_inflation = self.config["yearly_inflation"] / 365 if not self.config["no_broadcast"]: self.stm.wallet.unlock(self.config["wallet_password"]) self.scot_token = Token(self.config["scot_token"]) self.token_wallet = Wallet(self.config["scot_account"], steem_instance=self.stm) def get_token_holder(self): offset = 0 get_holder = self.scot_token.get_holder() offset += 1000 new_holder = self.scot_token.get_holder(offset=offset) while len(new_holder) > 0: get_holder.append(new_holder) offset += 1000 new_holder = self.scot_token.get_holder(offset=offset) token_per_100_vote = {} token_sum = 0 for item in get_holder: if item["account"] == self.config["scot_account"]: continue token_sum += float(item["balance"]) for item in get_holder: if item["account"] == self.config["scot_account"]: continue token_sum += float(item["balance"]) if float(item["balance"]) > 0: token_per_100_vote[item["account"]] = (float( item["balance"]) / token_sum) * self.daily_inflation / 10 return token_per_100_vote def get_token_to_sent(self, start_block, stop_block, token_per_100_vote): token_to_authors = {} b = Blockchain(steem_instance=self.stm) for op in b.stream(start=start_block, stop=stop_block, opNames=["vote"], max_batch_size=50): if op["voter"] not in token_per_100_vote: continue if not self.config["downvotes"] and op["weight"] < 0: continue if not self.config["upvotes"] and op["weight"] > 0: continue comment = Comment(op, steem_instance=self.stm) try: comment.refresh() except: print("Could not fetch %s" % comment["authorperm"]) continue json_metadata = comment["json_metadata"] app = None SETokensSupported = None if isinstance(json_metadata, str): json_metadata = json.loads(json_metadata) if "app" in json_metadata: app = json_metadata["app"] if isinstance(app, dict) and "name" in app: app = app["name"] elif isinstance(app, dict): app = "" if "SETokensSupported" in json_metadata: SETokensSupported = json_metadata["SETokensSupported"] app_or_symbol = False if app is not None and len( self.config["included_apps"] ) > 0 and app != "" and app in self.config["included_apps"]: app_or_symbol = True elif self.config["include_token_as_tag"] and self.scot_token[ "symbol"] in comment["tags"]: app_or_symbol = True elif SETokensSupported is not None and len( SETokensSupported ) > 0 and self.scot_token["symbol"] in SETokensSupported: app_or_symbol = True if not app_or_symbol and not self.config["include_all_posts"]: continue token_amount = abs( op["weight"]) / 10000 * token_per_100_vote[op["voter"]] if op["weight"] < 0: if op["voter"] not in token_to_authors: token_to_authors[op["voter"]] = token_amount else: token_to_authors[op["voter"]] += token_amount else: if op["author"] not in token_to_authors: token_to_authors[op["author"]] = token_amount else: token_to_authors[op["author"]] += token_amount return token_to_authors def get_token_transfer_last_24_h(self): yesterday = date.today() - timedelta(days=1) yesterday_0_0_0 = datetime(yesterday.year, yesterday.month, yesterday.day) yesterday_23_59_59 = datetime(yesterday.year, yesterday.month, yesterday.day, 23, 59, 59) token_sent_last_24_h = 0 for hist in self.token_wallet.get_history(self.scot_token["symbol"]): timestamp = datetime.strptime(hist["timestamp"], timeFormatZ) if timestamp <= yesterday_23_59_59: continue print(hist) if hist["from"] != self.config["scot_account"]: continue token_sent_last_24_h = float(hist["quantity"]) return token_sent_last_24_h def count_token(self, token_to_authors): token_amount_to_sent = 0 for author in token_to_authors: token_amount_to_sent += token_to_authors[author] return token_amount_to_sent def adapt_to_precision(self, token_to_authors): token_amount_to_sent = self.count_token(token_to_authors) for author in token_to_authors: token_to_authors[author] = token_to_authors[ author] * self.daily_inflation / token_amount_to_sent token_to_authors[author] = math.floor( token_to_authors[author] * 10**self.scot_token["precision"] ) / 10**self.scot_token["precision"] return token_to_authors def send_token(self, token_to_authors): for author in token_to_authors: if token_to_authors[author] < 10**(-self.scot_token["precision"]): continue if self.config["no_broadcast"]: logger.info("Sending %f %s to %s" % (token_to_authors[author], self.scot_token["symbol"], author)) else: self.token_wallet.transfer(author, token_to_authors[author], self.scot_token["symbol"], memo=self.config["token_memo"]) time.sleep(4) def run(self): b = Blockchain(steem_instance=self.stm) yesterday = date.today() - timedelta(days=1) yesterday_0_0_0 = datetime(yesterday.year, yesterday.month, yesterday.day) yesterday_23_59_59 = datetime(yesterday.year, yesterday.month, yesterday.day, 23, 59, 59) start_block = b.get_estimated_block_num(addTzInfo(yesterday_0_0_0)) stop_block = b.get_estimated_block_num(addTzInfo(yesterday_23_59_59)) logger.info("Check token transfer from %s..." % self.config["scot_account"]) token_sent_last_24_h = self.get_token_transfer_last_24_h() if token_sent_last_24_h > 0: logger.warning("Token were already sent today...") return logger.info("No token transfer were found, continue...") token_per_100_vote = self.get_token_holder() logger.info("%d token holder were found." % len(token_per_100_vote)) token_to_authors = self.get_token_to_sent(start_block, stop_block, token_per_100_vote) token_to_authors = self.adapt_to_precision(token_to_authors) token_amount_to_sent = self.count_token(token_to_authors) logger.info("Start to send %f token to %d accounts" % (token_amount_to_sent, len(token_to_authors))) self.send_token(token_to_authors)