示例#1
0
 def __init__(self,
              account,
              posting_key=None,
              active_key=None,
              nodes=None,
              db=None,
              probability_dimensions=None,
              min_age_to_vote=None,
              max_age_to_vote=None,
              minimum_vp_to_vote=None,
              vote_price=None):
     self.db = db
     self.nodes = nodes or ["https://api.steemit.com"]
     self.account = account
     self.client = Client(loglevel=logging.INFO)
     self.vote_client = Client(keys=[
         posting_key,
     ], nodes=nodes)
     self.refund_client = Client(keys=[
         active_key,
     ], nodes=nodes)
     self.min_age_to_vote = min_age_to_vote or 300
     self.max_age_to_vote = max_age_to_vote or 43200
     self.minimum_vp_to_vote = minimum_vp_to_vote or 80
     self.vote_percent = VotePercent(
         probability_dimensions=probability_dimensions)
     self.vote_price = Amount(vote_price) or Amount("1.000 STEEM")
示例#2
0
    def update_info(self, steem_per_mvest=None, account_detail=None):
        c = Client(nodes=["https://api.hivekings.com"])

        if not steem_per_mvest:
            # get chain properties
            dygp = c.get_dynamic_global_properties()
            steem_per_mvest = (
                float(Amount(dygp["total_vesting_fund_steem"]).amount) /
                (float(Amount(dygp["total_vesting_shares"]).amount) / 1e6))

        # get account detail
        if not account_detail:
            account_detail = c.get_accounts([self.username])[0]
        vests = float(Amount(account_detail["vesting_shares"]))

        # calculate account age
        t = parse(account_detail["created"])
        if t.tzinfo is None:
            utc_time = pytz.timezone('UTC')
            t = utc_time.localize(t)

        # account reputation
        acc = Account(c)
        acc.raw_data = account_detail

        self.reputation = acc.reputation(precision=4)
        self.sp = vests / 1e6 * steem_per_mvest
        self.vests = vests
        self.account_age = (timezone.now() - t).total_seconds() / 86400
        self.post_count = account_detail["post_count"]
        self.save()

        return self
示例#3
0
文件: backend.py 项目: emre/tiger
def upsert(table, delegation):
    """ Inserts or updates the delegation information to the database.

    If there is already a delegation registered from delegator to delegatee,
    it updates the row instead of creating a new one.

    :param table: table object of Dataset
    :param delegation: Delegation row from the steemd
    :return: None
    """
    query = dict(
        delegator=delegation["delegator"],
        delegatee=delegation["delegatee"],
    )

    amount_in_vests = float(Amount.from_asset(
        delegation["vesting_shares"]).amount)

    delegation_object = dict(
        delegator=delegation["delegator"],
        delegatee=delegation["delegatee"],
        vests=amount_in_vests,
        created_at=delegation["min_delegation_time"]
    )

    if table.find_one(**query):
        table.update(delegation_object, ['delegator', 'delegatee'])
    else:
        table.insert(delegation_object)
示例#4
0
    def handle(self, *args, **options):
        client = Client()
        acc = client.account(settings.CURATION_BOT_ACCOUNT)
        for index, transaction in acc.history(
                filter=["delegate_vesting_shares"],
                order="asc",
                only_operation_data=False,
        ):
            op = transaction["op"][1]
            if op.get("delegator") == settings.CURATION_BOT_ACCOUNT:
                continue

            if op.get("delegator") in BLACKLIST:
                continue

            try:
                sponsor = Sponsor.objects.get(username=op.get("delegator"))
                sponsor.delegation_modified_at = add_tz_info(
                    parse(transaction["timestamp"]))
            except Sponsor.DoesNotExist:
                sponsor = Sponsor(
                    username=op.get("delegator"),
                )
                sponsor.delegation_created_at = add_tz_info(
                    parse(transaction["timestamp"]))
            sponsor.delegation_amount = Amount(op.get("vesting_shares")).amount
            sponsor.save()

            print(f"Delegation of {op['delegator']}:"
                  f" {op['vesting_shares']} is saved.")
示例#5
0
 def test_asset_dict_output(self):
     amount = Amount('0.010 STEEM')
     asset_dict = amount.asset
     self.assertEqual({
         "amount": "10",
         "precision": 3,
         "nai": "@@000000021"
     }, asset_dict)
示例#6
0
 def test_asset_dict_input(self):
     amount = Amount.from_asset({
         'amount': '1029141630',
         'precision': 6,
         'nai': '@@000000037'
     })
     self.assertEqual(float('1029.141630'), float(amount.amount))
     self.assertEqual('VESTS', amount.symbol)
示例#7
0
 def handle(self, *args, **options):
     users = User.objects.all()
     c = LightsteemClient(nodes=["https://hived.emre.sh"])
     dygp = c.get_dynamic_global_properties()
     steem_per_mvest = (
             float(Amount(dygp["total_vesting_fund_hive"]).amount) /
             (float(Amount(dygp["total_vesting_shares"]).amount) / 1e6))
     c = LightsteemClient(nodes=["https://hived.emre.sh"])
     for chunk in chunks(users, 500):
         account_details = c.get_accounts([c.username for c in chunk])
         for account_detail in account_details:
             try:
                 related_user = User.objects.get(
                     username=account_detail["name"])
             except User.DoesNotExist:
                 print(f"{account_detail['name']} is not found. Skipping.")
                 continue
             print("updating", related_user)
             related_user.update_info(
                 steem_per_mvest=steem_per_mvest,
                 account_detail=account_detail,
             )
示例#8
0
    def get_cost(self, operation):
        preffered_api_type = self.client.api_type
        keys = self.client.keys
        if not len(keys):
            # add a dummy key
            self.client.keys = [
                "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
            ]
        try:
            tx = self.client.broadcast(operation, dry_run=True)
            signed_tx_hex = self.client.get_transaction_hex(tx)
            tx_size = len(bytes.fromhex(signed_tx_hex))

            self.client('condenser_api').get_dynamic_global_properties(
                batch=True)
            self.client('rc_api').get_resource_params(batch=True)
            self.client('rc_api').get_resource_pool(batch=True)

            chain_props, resource_params, resource_pool = self.client.\
                process_batch()

            resource_pool = resource_pool["resource_pool"]

            total_vesting_shares = int(
                Amount(chain_props["total_vesting_shares"]).amount)
            rc_regen = total_vesting_shares // (STEEM_RC_REGEN_TIME //
                                                STEEM_BLOCK_INTERVAL)
            model = RCModel(resource_params=resource_params,
                            resource_pool=resource_pool,
                            rc_regen=rc_regen)

            tx_cost = model.get_transaction_rc_cost(tx, tx_size)
            total_cost = sum(tx_cost["cost"].values())
            return total_cost
        finally:
            self.client.api_type = preffered_api_type
            self.client.keys = keys
示例#9
0
    def handle(self, *args, **options):
        active_key = getpass.getpass(
            f"Active key of f{settings.SPONSORS_ACCOUNT}")
        client = Client(keys=[active_key, ], nodes=["https://api.hivekings.com"])
        account = client.account(settings.SPONSORS_ACCOUNT)
        one_week_ago = now() - timedelta(days=7)
        sponsors = Sponsor.objects.filter(
            delegation_created_at__lt=one_week_ago,
            delegation_amount__gt=0,
            opt_in_to_rewards=True,
        )
        print(f"{sponsors.count()} sponsors found.")
        total_shares = Sponsor.objects.aggregate(
            total=Sum("delegation_amount"))["total"]
        print(f"{total_shares} VESTS delegated.")
        liquid_funds = Amount(account.raw_data["balance"])
        print(f"dpoll.sponsors has {liquid_funds}.")
        one_percent_share = liquid_funds.amount / 100

        transfers = []
        for sponsor in sponsors:
            shares_in_percent = Decimal(
                sponsor.delegation_amount * 100 / total_shares)
            amount = "%.3f" % (one_percent_share * shares_in_percent)
            transfers.append({
                "from": settings.SPONSORS_ACCOUNT,
                "to": sponsor.username,
                "amount": f"{amount} STEEM",
                "memo": f"Greetings {sponsor.username},"
                        " Thank you for supporting dPoll. "
                        "Here is your weekly rewards."
            })

        op_list = [Operation('transfer', op) for op in transfers]
        client.broadcast(op_list)
        print("Rewards are sent!")
示例#10
0
文件: views.py 项目: tdreid/dpoll.xyz
def steem_per_mvests():
    c = Client()
    info = c.get_dynamic_global_properties()
    return (float(Amount(info["total_vesting_fund_steem"]).amount) /
            (float(Amount(info["total_vesting_shares"]).amount) / 1e6))
示例#11
0
    def handle(self, *args, **options):
        """Entry point for the Django management command"""
        client = Client(keys=[
            settings.PROMOTION_ACCOUNT_ACTIVE_KEY,
        ],
                        nodes=["https://api.hivekings.com"])
        acc = client.account(settings.PROMOTION_ACCOUNT)
        for _, transaction in acc.history(
                filter=["transfer"],
                only_operation_data=False,
        ):

            op = transaction["op"][1]

            # only process incoming transactions
            if op["from"] == settings.PROMOTION_ACCOUNT:
                continue

            try:
                promotion_transaction = PromotionTransaction.objects.get(
                    trx_id=transaction["trx_id"])
                # if transaction already exists, means what we already
                #  processed it. so, we can skip it safely.
                print(f"This transaction is already processed."
                      f"Skipping. ({transaction['trx_id']})")
                continue
            except PromotionTransaction.DoesNotExist:
                amount = Amount(op["amount"])
                promotion_amount = '%.3f' % float(amount.amount)
                # create a base transaction first
                promotion_transaction = PromotionTransaction(
                    trx_id=transaction["trx_id"],
                    from_user=op["from"],
                    amount=promotion_amount,
                    memo=op["memo"],
                )
                promotion_transaction.save()

                # check if the asset is valid
                if amount.symbol == "STEEM":
                    print(f"Invalid Asset. Refunding. ({op['amount']})")
                    self.refund(client, op["from"], op["amount"],
                                "Only SBD is accepted.")
                    continue

                # check if the memo is valid
                memo = op["memo"]
                try:
                    author = memo.split("@")[1].split("/")[0]
                    permlink = memo.split("@")[1].split("/")[1]
                except IndexError as e:
                    print(f"Invalid URL. Refunding. ({memo})")
                    self.refund(client, op["from"], op["amount"],
                                "Invalid URL")
                    continue

                # check if the poll exists
                try:
                    question = Question.objects.get(username=author,
                                                    permlink=permlink)
                except Question.DoesNotExist:
                    print(f"Invalid poll. Refunding. ({memo})")
                    self.refund(client, op["from"], op["amount"],
                                "Invalid poll.")
                    continue

                # if the poll is closed, don't mind promoting it.
                if question.expire_at < timezone.now():
                    print(f"Expired poll. Refunding. ({memo})")
                    self.refund(client, op["from"], op["amount"],
                                "Expired poll.")
                    continue

                promotion_transaction.author = author
                promotion_transaction.permlink = permlink
                promotion_transaction.save()

                # update the related poll's promotion amount
                if not question.promotion_amount:
                    question.promotion_amount = float(amount.amount)
                else:
                    question.promotion_amount += float(amount.amount)
                question.save()

                print(f"{author}/{permlink} promoted with "
                      f"{promotion_amount} STEEM.")
示例#12
0
    def process_transfer(self, transaction_data):

        op = transaction_data["op"][1]
        amount = Amount(op["amount"])

        # check if transaction is already registered in the database
        if self.db.is_transfer_already_registered(transaction_data["trx_id"]):
            logger.info(
                "Transaction is already registered. Skipping. (TRX: %s)",
                transaction_data["trx_id"])
            return

        # register the transaction into db
        self.db.register_incoming_transaction(
            op["from"],
            op["memo"],
            transaction_data["block"],
            transaction_data["trx_id"],
        )

        # check if the asset is valid
        if amount.symbol != "STEEM":
            logger.info(
                "Invalid asset. Refunding %s with %s. (TRX: %s)",
                op["from"],
                amount,
                transaction_data["trx_id"],
            )
            self.refund(
                op["from"],
                op["amount"],
                RefundReason.INVALID_ASSET.value,
                transaction_data["trx_id"],
            )
            return

        # check if the VP is suitable
        # Check the VP
        acc = self.client.account(self.account)
        if acc.vp() < self.minimum_vp_to_vote:
            print(acc.vp(), self.minimum_vp_to_vote)
            logger.info("Rando is sleeping. Refunding. (TRX: %s)",
                        transaction_data["trx_id"])
            self.refund(
                op["from"],
                op["amount"],
                RefundReason.SLEEP_MODE.value,
                transaction_data["trx_id"],
            )
            return

        # check vote price
        if amount.amount != self.vote_price.amount:
            logger.info("Invalid amount. Refunding. (TRX: %s)",
                        transaction_data["trx_id"])
            self.refund(
                op["from"],
                op["amount"],
                "Invalid amount. You need to send %s" % self.vote_price,
                transaction_data["trx_id"],
            )
            return

        # check if the sender is in a blacklist
        if self.in_global_blacklist(op["from"]):
            logger.info("Sender is in blacklist. Refunding. (TRX: %s)",
                        transaction_data["trx_id"])

            self.refund(
                op["from"],
                op["amount"],
                RefundReason.SENDER_IN_BLACKLIST.value,
                transaction_data["trx_id"],
            )
            return

        # check if the memo is valid
        memo = op["memo"]
        try:
            author = memo.split("@")[1].split("/")[0]
            permlink = memo.split("@")[1].split("/")[1]
        except IndexError as e:
            logger.info("Invalid URL. Refunding. Memo: %s", memo)
            self.refund(
                op["from"],
                op["amount"],
                RefundReason.INVALID_URL.value,
                transaction_data["trx_id"],
            )
            return

        # check if the author is in a blacklist
        if self.in_global_blacklist(author):
            logger.info("Author is in blacklist. Refunding. (TRX: %s)",
                        transaction_data["trx_id"])

            self.refund(
                op["from"],
                op["amount"],
                RefundReason.AUTHOR_IN_BLACKLIST.value,
                transaction_data["trx_id"],
            )
            return

        # check is the Comment is a valid Comment
        comment_content = self.get_content(author, permlink)
        if comment_content["id"] == 0:
            logger.info("Invalid post. Refunding. (TRX id: %s)",
                        transaction_data["trx_id"])
            self.refund(
                op["from"],
                op["amount"],
                RefundReason.INVALID_URL.value,
                transaction_data["trx_id"],
            )
            return

        # check comment is valid
        if comment_content.get("parent_author"):
            logger.info("Not a main post. Refunding. (TRX id: %s)",
                        transaction_data["trx_id"])
            self.refund(
                op["from"],
                op["amount"],
                RefundReason.INVALID_URL.value,
                transaction_data["trx_id"],
            )
            return

        # check if we've already voted for that post
        active_voters = self.get_active_votes(author, permlink)
        if self.account in active_voters:
            logger.info("Already voted. Refunding. (TRX id: %s)",
                        transaction_data["trx_id"])
            self.refund(
                op["from"],
                op["amount"],
                RefundReason.POST_IS_ALREADY_VOTED.value,
                transaction_data["trx_id"],
            )
            return

        # check if the Comment age is suitable
        created = parse(comment_content["created"])
        comment_age = (datetime.now() - created).total_seconds()
        if not (self.min_age_to_vote < comment_age < self.max_age_to_vote):
            self.refund(
                op["from"],
                op["amount"],
                f"Post age must be between {self.min_age_to_vote} and"
                f" {self.max_age_to_vote} seconds",
                transaction_data["trx_id"],
            )
            logger.info("Post age is invalid. Refunding. (TRX id: %s)",
                        transaction_data["trx_id"])
            return

        # vote
        self.vote(author, permlink, amount, transaction_data)
示例#13
0
def steem_per_mvests():
    c = Client(nodes=["https://api.hivekings.com"])
    info = c.get_dynamic_global_properties()
    return (float(Amount(info["total_vesting_fund_steem"]).amount) /
            (float(Amount(info["total_vesting_shares"]).amount) / 1e6))
示例#14
0
 def test_standard_input(self):
     amount = Amount('1.942 SBD')
     self.assertEqual(float(1.942), float(amount.amount))
     self.assertEqual('SBD', amount.symbol)