holgern / beem Goto Github PK
View Code? Open in Web Editor NEWA python library to interact with the HIVE blockchain
Home Page: http://beem.readthedocs.io/en/latest/
License: Other
A python library to interact with the HIVE blockchain
Home Page: http://beem.readthedocs.io/en/latest/
License: Other
Account.history(start, stop)
with start
and stop
being datetime instances should return all account operations between the given timestamps
Account.history(start, stop)
sometimes fails with a ZeroDivisionError
exception:
Traceback (most recent call last):
File "history.py", line 15, in <module>
for op in a.history(start, stop):
File "/usr/local/lib/python3.6/site-packages/beem/account.py", line 1566, in history
op_est = self.estimate_virtual_op_num(start, stop_diff=1)
File "/usr/local/lib/python3.6/site-packages/beem/account.py", line 1333, in estimate_virtual_op_num
op_diff = (blocktime - formatTimeString(trx["timestamp"])).total_seconds() / factor
ZeroDivisionError: float division by zero
What actually fails is the op number lookup for a given timestamp via Account.estimate_virtual_op_num()
. Here's a minimum example to reproduce the problem:
from beem.account import Account
from datetime import datetime, timedelta
from beem.utils import addTzInfo
a = Account("berniesanders")
start = addTzInfo(datetime(2017, 11, 16, 23, 23, 11))
print(a.estimate_virtual_op_num(start))
Output:
# python bug_divbyzero.py
Traceback (most recent call last):
File "bug_divbyzero.py", line 9, in <module>
print(a.estimate_virtual_op_num(start))
File "/usr/local/lib/python3.6/site-packages/beem/account.py", line 1333, in estimate_virtual_op_num
op_diff = (blocktime - formatTimeString(trx["timestamp"])).total_seconds() / factor
ZeroDivisionError: float division by zero
The following quick-hack solves the problem in this case:
diff --git a/beem/account.py b/beem/account.py
index e100a58..c840185 100644
--- a/beem/account.py
+++ b/beem/account.py
@@ -1329,6 +1329,7 @@ class Account(BlockchainObject):
factor = (formatTimeString(op_start_last[0][1]["timestamp"]) - formatTimeString(trx["timestamp"])).total_seconds() / diff_op
elif not isinstance(blocktime, (datetime, date, time)) and diff_op != 0:
factor = (op_start_last[0][1]["block"] - trx["block"]) / diff_op
+ factor = min(1, factor)
if isinstance(blocktime, (datetime, date, time)):
op_diff = (blocktime - formatTimeString(trx["timestamp"])).total_seconds() / factor
else:
However, there are more instances where a division by factor
is done and I'm not sure if the change affects the correctness of the resulting block number.
# beempy --version
beempy, version 0.19.40
# python --version
Python 3.6.5
With how enormous the changelog is, it makes the README.rst
file (which, as the name implies, should be read in it's entirety) much too long.
With the frequent updates to beem, keeping the changelog there is unsustainable. I propose moving it to an another file (changelog.rst
?) or into the Wiki pages of the repository.
I'd like to see some more information why one should use your library over Steem-Python in your readme.md
Comment class in beem.comment has a helper method to initiate upvotes called as .upvote
.
This should work as expected on all cases.
Beem fails to create an upvote transaction if the comment will be upvoted doesn't have any vote before. This is happening because of this check on the library.
Here is a little python script to reproduce the issue:
from beem.comment import Comment
from beem.steem import Steem
ACCOUNT = "<upvoter_account_username>"
def reproduce(s):
main_comment = Comment("@beemtutorials/test-case-for-beem-upvote", steem_instance=s)
reply = main_comment.reply("test-comment", author=ACCOUNT)
reply_comment = Comment(reply["operations"][0][1])
reply_comment.upvote(+50, voter=ACCOUNT)
def main():
s = Steem(
node=["https://rpc.buildteam.io"],
keys=["<posting_wif>"]
)
reproduce(s)
if __name__ == '__main__':
main()
Stacktrace:
/Users/emre/Environments/beemtutorials/bin/python /Users/emre/Projects/beem_tutorials/repro_bug.py
Traceback (most recent call last):
File "/Users/emre/Projects/beem_tutorials/repro_bug.py", line 23, in <module>
main()
File "/Users/emre/Projects/beem_tutorials/repro_bug.py", line 19, in main
reproduce(s)
File "/Users/emre/Projects/beem_tutorials/repro_bug.py", line 11, in reproduce
reply_comment.upvote(+50, voter=ACCOUNT)
File "/Users/emre/Environments/beemtutorials/lib/python3.6/site-packages/beem/comment.py", line 555, in upvote
raise VotingInvalidOnArchivedPost
beem.exceptions.VotingInvalidOnArchivedPost
Browser/App version: N/A, beem-0.19.47
Operating system: N/A
b.stream(start=start, stop=stop, threading=True, thread_num=8)
should return all ops from the given block range and fetch the data with 8 threads in the background.
The script throws lots of connection errors from various nodes and is comparably slow. Running the same call with threading=False
works without any error and is typically even faster.
#!/usr/bin/python
from beem.blockchain import Blockchain
import sys
b = Blockchain()
opcount = 0
for op in b.stream(start=23483000, stop=23483200, threading=True, thread_num=8,
opNames=['vote']):
sys.stdout.write("\r%s" % op['block_num'])
opcount += 1
print("\n", opcount)
Output:
# time python bug_threading.py
23483103Error: Invalid error code (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.pevo.science (1/-1)
Error: rsv is not implemented, yet
Lost connection or internal error on node: wss://steemd.pevo.science (2/-1)
Error: [Errno 9] Bad file descriptor
Error: Invalid WebSocket Header
Lost connection or internal error on node: wss://steemd.pevo.science (4/-1)
Lost connection or internal error on node: wss://steemd.pevo.science (4/-1)
Retrying in 5 seconds
Error: Handshake status 503 Service Temporarily Unavailable
Lost connection or internal error on node: wss://steemd.pevo.science (5/-1)
Retrying in 6 seconds
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.pevo.science (6/-1)
Error: Connection is already closed.
Lost connection or internal error on node: wss://steemd.pevo.science (7/-1)
Retrying in 9 seconds
Error: Handshake status 503 Service Temporarily Unavailable
Lost connection or internal error on node: wss://steemd.pevo.science (8/-1)
Retrying in 11 seconds
Error: Handshake status 503 Service Temporarily Unavailable
Lost connection or internal error on node: wss://steemd.pevo.science (9/-1)
Retrying in 12 seconds
Error: Handshake status 503 Service Temporarily Unavailable
Lost connection or internal error on node: wss://steemd.pevo.science (10/-1)
Retrying in 10 seconds
Error: rsv is not implemented, yet
Lost connection or internal error on node: wss://steemd.pevo.science (11/-1)
Error: Connection is already closed.
Lost connection or internal error on node: wss://steemd.pevo.science (12/-1)
Retrying in 10 seconds
23483255Error: Invalid error code (_ssl.c:2273)
Lost connection or internal error on node: wss://rpc.steemviz.com (1/-1)
Error: [Errno 11] Resource temporarily unavailable
Lost connection or internal error on node: wss://rpc.steemviz.com (2/-1)
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://rpc.steemviz.com (4/-1)
Retrying in 5 seconds
Lost connection or internal error on node: wss://rpc.steemviz.com (4/-1)
Error: [Errno 9] Bad file descriptor
Lost connection or internal error on node: wss://rpc.steemviz.com (5/-1)
Retrying in 6 seconds
Error: [Errno 9] Bad file descriptor
Lost connection or internal error on node: wss://rpc.steemviz.com (6/-1)
Retrying in 8 seconds
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://rpc.steemviz.com (8/-1)
Lost connection or internal error on node: wss://rpc.steemviz.com (8/-1)
Retrying in 11 seconds
Error: rsv is not implemented, yet
Error: rsv is not implemented, yet
Lost connection or internal error on node: wss://rpc.steemviz.com (10/-1)
Lost connection or internal error on node: wss://rpc.steemviz.com (10/-1)
Error: rsv is not implemented, yet
Lost connection or internal error on node: wss://rpc.steemviz.com (11/-1)
Error: Invalid error code (_ssl.c:2273)
Lost connection or internal error on node: wss://rpc.steemviz.com (12/-1)
Retrying in 10 seconds
Error: rsv is not implemented, yet
Lost connection or internal error on node: wss://rpc.steemviz.com (13/-1)
Error: [SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] decryption failed or bad record mac (_ssl.c:2273)
Lost connection or internal error on node: wss://rpc.steemviz.com (14/-1)
Retrying in 10 seconds
Error: Connection is already closed.
Lost connection or internal error on node: wss://rpc.steemviz.com (15/-1)
Retrying in 10 seconds
23483415Error: Invalid error code (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (1/-1)
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (3/-1)
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (3/-1)
Retrying in 3 seconds
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (4/-1)
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (5/-1)
Retrying in 6 seconds
Error: rsv is not implemented, yet
Error: Invalid error code (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (7/-1)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (7/-1)
Retrying in 9 seconds
Error: Invalid error code (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (8/-1)
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (9/-1)
Error: [Errno 9] Bad file descriptor
Error: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (11/-1)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (11/-1)
Retrying in 10 seconds
Error: [Errno 9] Bad file descriptor
Error: 'utf-8' codec can't decode byte 0xf8 in position 0: invalid start byte
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (13/-1)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (13/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (14/-1)
Retrying in 10 seconds
Error: rsv is not implemented, yet
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (15/-1)
Error: [SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] Invalid error code (_ssl.c:2273)
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (16/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (17/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (18/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (19/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (20/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (21/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (22/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (23/-1)
Retrying in 10 seconds
Error: The read operation timed out
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (24/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (25/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (26/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (27/-1)
Retrying in 10 seconds
Error: [Errno 111] Connection refused
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (28/-1)
Retrying in 10 seconds
23483500
12230
real 4m40.085s
user 0m32.147s
sys 0m1.010s
The script takes considerably long to run and errors are shown from various nodes. The log (across several runs of the script above) contains errors I haven't seen before from typical node/connection issues:
Error: socket is already closed.
Error: rsv is not implemented, yet
Error: Handshake status 400 Bad Reest
Error: invalid literal for int() with base 10: '07:16:40' # <- this was utcnow() at that time
Error: invalid literal for int() with base 10: 'Tm7e05+XYwFFwwm+UDClM9rFIfo='
Error: invalid literal for int() with base 10: '(Ubuntu)'
Error: Illegal frame
Error: ('Invalid opcode %r', 6)
Error: ('Underlying socket has been closed.',)
The same without threading:
#!/usr/bin/python
from beem.blockchain import Blockchain
import sys
b = Blockchain()
opcount = 0
for op in b.stream(start=23483000, stop=23483500, threading=False, thread_num=8,
opNames=['vote']):
sys.stdout.write("\r%s" % op['block_num'])
opcount += 1
print("\n", opcount)
Output:
# time python bug_threading.py
23483500
12230
real 0m52.549s
user 0m15.767s
sys 0m0.527s
No connection error, and the single-threaded version is faster than the multi-threaded version.
# beempy --version
beempy, version 0.19.40
# python --version
Python 3.6.5
The vests_to_rshares function of the beem.steem module should return the number of rshares a vote by an account dependent on the vests and the voting power the account has, and the vote percentage that account uses for voting.
Instead, that function returns the rshares that it should return, but 1e6 times smaller. This issue happens because the vests would need to be multiplied with 1e6 in order to be in the right scope for the calculation (relevant tutorial) This would need to be added here.
from beem.steem import Steem
stm = Steem()
)stm.vests_to_rshares(10000000)
)stm.rshares_to_sbd(200000)
)stm.vests_to_sbd(10000000)
)It looks like this in a REPL:
>>> from beem.steem import Steem
>>> stm = Steem()
>>> stm.vests_to_rshares(10000000)
200000
^This is where the issue is. That should be 200000000000 instead
>>> stm.rshares_to_sbd(200000)
3.3005542087518333e-07
>>> stm.vests_to_sbd(10000000)
0.33005542087518336
After applying a fix, it would look like that:
>>> from beem.steem import Steem
>>> stm = Steem()
>>> stm.vests_to_rshares(10000000)
200000000000
>>> stm.rshares_to_sbd(200000000000)
0.33005542087518336
>>> stm.vests_to_sbd(10000000)
0.33005542087518336
I want to join on your TR
I am getting key already in storage
when adding a key to the wallet on the Vit network.
When trying to use the key, it says
beem.exceptions.MissingKeyError
I have tried removing the key, and adding again. No luck.
beempy --node https://jussi.vit.tube listaccounts
Does not show the key.
Key was added (and removed) with --node https://jussi.vit.tube
parameter.
It only happens to specific accounts, not all and on specific machines, where other keys work fine, but not some.
Discussions.get_discussions('blog', query)
should return a number of blog posts from a steem account based on the query
parameter.
Discussions.get_discussions('blog', query)
may return the same two posts over and over
from beem.discussions import Query, Discussions
start_author = "crokkon"
start_permlink = "how-to-find-out-which-of-your-steem-apps-just-acted-in-your-name"
query_limit = 20
query = Query(start_author=start_author,
start_permlink=start_permlink, limit=query_limit,
tag=start_author)
dis = Discussions()
count = 0
for d in dis.get_discussions("blog", query):
print(("%d. " % (count + 1)) + str(d))
count += 1
Output:
1. <Comment @crokkon/how-to-find-out-which-of-your-steem-apps-just-acted-in-your-name>
2. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
3. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
4. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
5. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
6. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
7. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
8. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
9. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
10. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
11. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
12. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
13. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
14. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
15. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
16. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
17. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
18. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
19. <Comment @crokkon/cashout-chains-steem-from-7400-accounts-leaves-steem-via-only-a-few-accounts>
20. <Comment @paulag/business-intelligence-steemit-weekly-contest-11-and-winner-10>
...
Hello,
In playing around with beempy this morning I found that since accounts can be created with 0 SP, using beempy to look up account power can lead to division by zero:
$ beempy power scms-sc
@scms-sc
Traceback (most recent call last):
File "/Environments/alpha/bin/beempy", line 11, in <module>
sys.exit(cli())
File "/Environments/alpha/lib/python3.6/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/Environments/alpha/lib/python3.6/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/Environments/alpha/lib/python3.6/site-packages/click/core.py", line 1163, in invoke
rv.append(sub_ctx.command.invoke(sub_ctx))
File "/Environments/alpha/lib/python3.6/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Environments/alpha/lib/python3.6/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/Environments/alpha/lib/python3.6/site-packages/beem/cli.py", line 974, in power
a.print_info(use_table=True)
File "/Environments/alpha/lib/python3.6/site-packages/beem/account.py", line 320, in print_info
vote_mana = self.get_manabar()
File "/Environments/alpha/lib/python3.6/site-packages/beem/account.py", line 403, in get_manabar
estimated_pct = estimated_mana / estimated_max * 100
ZeroDivisionError: division by zero
I'm sorry I don't know the fix (adding some prettier error handling code somewhere?), I don't know much python.
discussions.Discussions_by_feed()
should return an account's feed entries. If the account doesn't follow any other account, the result should be empty.
discussions.Discussions_by_feed()
returns an account's feed entries if there are entries available. If there are no entries available, beem iterates over all nodes and fails to return an empty result.
from beem.discussions import Discussions_by_feed, Query
from beem.account import Account
account = Account('stmdev')
query = Query(limit=20, tag=account['name'])
for entry in Discussions_by_feed(query):
print(entry)
Result:
Error: Empty Reply
Lost connection or internal error on node: wss://steemd.minnowsupportproject.org (1/-1)
Error: Empty Reply
Lost connection or internal error on node: wss://rpc.steemviz.com (1/-1)
Error: Empty Reply
Lost connection or internal error on node: wss://rpc.buildteam.io (1/-1)
Error: Empty Reply
Lost connection or internal error on node: wss://steemd.privex.io (1/-1)
Error: Empty Reply
Lost connection or internal error on node: https://api.steemit.com (1/-1)
Error: Empty Reply
Lost connection or internal error on node: https://rpc.buildteam.io (1/-1)
Error: Empty Reply
Lost connection or internal error on node: https://rpc.steemviz.com (1/-1)
...
The reason is that beem by default switches to the next node if an RPC reply is empty. However, an empty reply is the correct reply in this case. Some classes in beem.discussions
are missing the corresponding code to handle this situation:
self.steem.rpc.set_next_node_on_empty_reply(self.steem.rpc.get_use_appbase())
blockchain.get_all_accounts(limit=2000, steps=1000)
returns 2000 account names while internally doing two batch calls of 1000 accounts each. This should work on both appbase and non-appbase nodes
blockchain.get_all_accounts(limit=2000, steps=1000)
fails on appbase nodes when limit
> steps
>>> from beem import Steem
>>> from beem.blockchain import Blockchain
>>> s = Steem(node='https://api.steemit.com')
>>> s.rpc.get_use_appbase()
True
>>> len(list(b.get_all_accounts(limit=1000, steps=1000)))
1000
>>> len(list(b.get_all_accounts(limit=2000, steps=1000)))
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/beemapi/steemnoderpc.py", line 65, in rpcexec
reply = super(SteemNodeRPC, self).rpcexec(payload)
File "/usr/local/lib/python3.6/site-packages/beemapi/graphenerpc.py", line 381, in rpcexec
raise RPCError(ret['error']['message'])
beemapi.exceptions.RPCError: Bad Cast:Invalid cast from object_type to string
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/beem/blockchain.py", line 562, in get_all_accounts
ret = self.steem.rpc.list_accounts({'start': lastname, 'limit': steps, 'order': 'by_name'}, api="database")["accounts"]
File "/usr/local/lib/python3.6/site-packages/beemapi/graphenerpc.py", line 430, in method
r = self.rpcexec(query)
File "/usr/local/lib/python3.6/site-packages/beemapi/steemnoderpc.py", line 87, in rpcexec
doRetry = self._check_error_message(e, self.error_cnt_call)
File "/usr/local/lib/python3.6/site-packages/beemapi/steemnoderpc.py", line 146, in _check_error_message
raise exceptions.UnhandledRPCError(msg)
beemapi.exceptions.UnhandledRPCError: Bad Cast:Invalid cast from object_type to string
It works on non-appbase nodes:
>>> s = Steem("wss://steemd.pevo.science")
>>> s.rpc.get_use_appbase()
False
>>> b = Blockchain(steem_instance=s)
>>> len(list(b.get_all_accounts(limit=2000, steps=1000)))
2000
# beempy --version
beempy, version 0.19.37
# python --version
Python 3.6.5
Account.get_rc_manabar()
should return the current RC mana state of an Account
Account.get_rc_manabar()
may raise a ZeroDivisionError
exception if the corresponding account has a max_rc
bandwidth of 0.
from beem.account import Account
a = Account('a-pile-of-steem')
print(a.get_rc_manabar())
Traceback (most recent call last):
File "bug_rc.py", line 3, in <module>
print(a.get_rc_manabar())
File "/usr/local/lib/python3.6/site-packages/beem/account.py", line 241, in get_rc_manabar
current_pct = current_mana / max_mana * 100
ZeroDivisionError: division by zero
# beempy --version
beempy, version 0.20.6
# python --version
Python 3.6.6
account.history()
and account.get_account_history()
should return only the first blockchain operation of an account when called with start=0, stop=0, use_block_num=False
.
account.history()
returns the full history and account.get_account_history()
returns limit+1
operations when called with start=0, stop=0, use_block_num=False
.
from beem.account import Account
import sys
opnum = int(sys.argv[1])
a = Account("stmdev")
ops = list(a.history(opnum, opnum, use_block_num=False))
print("a.history() returned %d ops" % (len(ops)))
ops = list(a.history_reverse(opnum, opnum, use_block_num=False))
print("a.history_reverse() returned %d ops" % (len(ops)))
ops = list(a.get_account_history(index=opnum+1, limit=opnum+1,
start=opnum, stop=opnum,
use_block_num=False))
print("a.get_account_history() returned %d ops" % (len(ops)))
Output:
# python getop.pyy 0
a.history() returned 1756 ops
a.history_reverse() returned 1 ops
a.get_account_history() returned 2 ops
The same for operation number 1 works:
# python getop.py 1
a.history() returned 1 ops
a.history_reverse() returned 1 ops
a.get_account_history() returned 1 ops
# beempy --version
beempy, version 0.19.34
# python --version
Python 3.6.5
history()
, history_reverse()
, and get_account_history()
check for if start
/ if stop
at several stages, however this check is False
for both None
and 0
. Changing those checks to if start is not None
/ if stop is not None
could solve this:
# python getop.py.py 0
a.history() returned 1 ops
a.history_reverse() returned 1 ops
a.get_account_history() returned 1 ops
# python getop.py.py 1
a.history() returned 1 ops
a.history_reverse() returned 1 ops
a.get_account_history() returned 1 ops
steem.post()
brings two options to set beneficiaries:
comment_options
in the form of: comment_options = {
'max_accepted_payout': '1000000.000 SBD',
'percent_steem_dollars': 10000,
'allow_votes': True,
'allow_curation_rewards': True,
'extensions': [[0, {
'beneficiaries': [
{'account': 'account1', 'weight': 5000},
{'account': 'account2', 'weight': 5000},
]}
]]
}
beneficiaries
in the form of: beneficiaries = [
{'account': 'account1', 'weight': 5000},
{'account': 'account2', 'weight': 5000}
]
The list in beneficiaries
is supposed to override the settings in the comment_options
if both parameters are present.
It is not possible to set beneficiaries using either method.
comment_options
, dry run, creating an unsigned transaction that is not broadcasted:from beem import Steem
import json
s = Steem(nobroadcast=True, unsigned=True)
comment_options = {
'max_accepted_payout': '1000000.000 SBD',
'percent_steem_dollars': 10000,
'allow_votes': True,
'allow_curation_rewards': True,
'extensions': [[0, {
'beneficiaries': [
{'account': 'account1', 'weight': 5000},
{'account': 'account2', 'weight': 5000},
]}
]]
}
tx = s.post(title="title", body="body", permlink="permlink",
author="author", comment_options=comment_options,
beneficiaries=None)
print(json.dumps(tx, indent=2))
Result:
[...]
[
"comment_options",
{
"author": "author",
"permlink": "permlink",
"max_accepted_payout": "1000000.000 SBD",
"percent_steem_dollars": 10000,
"allow_votes": true,
"allow_curation_rewards": true,
"extensions": []
}
]
The resulting extensions
field is empty, the post will be created but without beneficiaries.
beneficiary
parameter:from beem import Steem
import cfg_stmdev as cfg
import time
import json
s = Steem(keys=[cfg.POSTING_WIF], nobroadcast=False)
comment_options = {
'max_accepted_payout': '1000000.000 SBD',
'percent_steem_dollars': 10000,
'allow_votes': True,
'allow_curation_rewards': True,
}
beneficiaries = [{'account': 'stmdev', 'weight': 1000}]
reply_identifier = '@stmdev/pwdtest'
timestamp = int(time.time())
permlink = 'reply-case-1-%s' % timestamp
body = "%s %s" % (comment_options, beneficiaries)
tx = s.post(title=permlink, body=body, permlink=permlink,
author=cfg.ACCOUNT, reply_identifier=reply_identifier,
comment_options=comment_options,
beneficiaries=beneficiaries)
print(json.dumps(tx, indent=2))
The list of beneficiaries is now part of the transaction, but the operation fails with a missing required posting authority
exception:
[...]
{"ops":[["comment",{"parent_author":"stmdev","parent_permlink":"pwdtest","author":"stmdev","permlink":"reply-case-1-1528013878","title":"reply-case-1-1528013878","body":"{'max_accepted_payout': '1000000.000 SBD', 'percent_steem_dollars': 10000, 'allow_votes': True, 'allow_curation_rewards': True} [{'account': 'stmdev', 'weight': 1000}]","json_metadata":"{\"app\": \"beem/0.19.35\"}"}],["comment_options",{"author":"stmdev","permlink":"reply-case-1-1528013878","max_accepted_payout":"1000000.000 SBD","percent_steem_dollars":10000,"allow_votes":true,"allow_curation_rewards":true,"extensions":[[0,{"beneficiaries":[{"account":"stmdev","weight":1000}]}]]}]],"sigs":["STM6x286end3rLZj9ornAaxBaVzovxjHtXzBQppSFXCe67gCMu3xq"]}
[...]
beemapi.exceptions.UnhandledRPCError: missing required posting authority
The used posting key is correct, the same script creates a post with beneficiaries=None
.
Possibly related: steemit/steem-python#9
# beempy --version
beempy, version 0.19.35
# python --version
Python 3.6.5
Should be "irreversible" right?
beem/steem.py (ll. 54 and 130)
The used power
calculation via steem._calc_resulting_vote()
should handle both up- and downvotes in the same way and both should consume the same amount of voting power.
Upvotes are handled correctly, but downvotes may give incorrect/different results in some cases.
cd examples
python plot_vp_over_time.py crokkon
The voting power is partly shown with values above 100.
Another effect is that rshares_to_vote_pct()
may give different absolute vote percentages for up- and downvotes for the same absolute amount of rshares:
>>> s.rshares_to_vote_pct(1e12, vests=412125123351512)
1250
>>> s.rshares_to_vote_pct(-1e12, vests=412125123351512)
-1200
The reason is that steem._calc_resulting_vote()
treats the voting percentage as a signed value. A negative voting percentage (=flag/downvote) gives a negative used_power
, while this number has to be positive in any case. This value is subtracted from the previous voting power for plotting, eventually giving VP values > 100%.
I was trying to do pip install beem
in order to run your steemmonsters app, but beem depends on Scrypt, and Scrypt doesn't seem to be able to run on Windows. I tried to install the OpenSSL package that it requires, but I failed. I don't exactly know what else it needs. I installed this and added it to my path.
The following is the error that I got.
crypto_aes.c
scrypt-1.2.1/libcperciva/crypto/crypto_aes.c(6): fatal error C1083: No se puede abrir el archivo incluir: 'openssl/aes.h': No such file or directory
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.15.26726\\bin\\HostX86\\x64\\cl.exe' failed with exit status 2
----------------------------------------
Command "c:\python37\python.exe -u -c "import setuptools, tokenize;
__file__='C:\\Users\\pc\\AppData\\Local\\Temp\\pip-install-6w9w987_\\scrypt\\setup.py';
f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();
exec(compile(code, __file__, 'exec'))
"install --record C:\Users\pc\AppData\Local\Temp\pip-record-eu_c56pk\install-record.txt
--single-version-externally-managed --compile" failed with error code 1 in
C:\Users\pc\AppData\Local\Temp\pip-install-6w9w987_\scrypt\
Blockchain.stream(threading=True)
should use threads to fetch several blocks in parallel. Each block should be fetched once from the RPC node.
Blockchain.stream(threading=True)
requests blocks twice from the RPC node, if those block don't contain operations or only virtual operations. This limits the benefits from the parallel threads.
from beem.blockchain import Blockchain
b = Blockchain()
for op in b.stream(start=2500000, stop=2500010, threading=True):
continue
Plus printf-debugging:
index 5cb196c..2e19545 100644
--- a/beemapi/steemnoderpc.py
+++ b/beemapi/steemnoderpc.py
@@ -53,6 +53,7 @@ class SteemNodeRPC(GrapheneRPC):
:raises ValueError: if the server does not respond in proper JSON format
:raises RPCError: if the server returns an error
"""
+ print(payload)
if self.url is None:
raise except
Output:
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 1}
{'method': 'call', 'params': ['database_api', 'get_dynamic_global_properties', []], 'jsonrpc': '2.0', 'id': 2}
{'method': 'call', 'params': ['database_api', 'get_feed_history', []], 'jsonrpc': '2.0', 'id': 3}
{'method': 'call', 'params': ['database_api', 'get_feed_history', []], 'jsonrpc': '2.0', 'id': 4}
{'method': 'call', 'params': ['database_api', 'get_next_scheduled_hardfork', []], 'jsonrpc': '2.0', 'id': 5}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 6}
{'method': 'call', 'params': ['database_api', 'get_witness_schedule', []], 'jsonrpc': '2.0', 'id': 7}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 8}
{'method': 'call', 'params': ['database_api', 'get_reward_fund', ['post']], 'jsonrpc': '2.0', 'id': 9}
{'method': 'call', 'params': ['database_api', 'get_dynamic_global_properties', []], 'jsonrpc': '2.0', 'id': 10}
{'method': 'call', 'params': [None, 'get_block', [25031061]], 'jsonrpc': '2.0', 'id': 11}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 1}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 1}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 1}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 1}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 1}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 1}
{'method': 'call', 'params': ['database_api', 'get_config', []], 'jsonrpc': '2.0', 'id': 1}
{'method': 'call', 'params': [None, 'get_block', [2500000]], 'jsonrpc': '2.0', 'id': 12}
{'method': 'call', 'params': [None, 'get_block', [2500001]], 'jsonrpc': '2.0', 'id': 2}
{'method': 'call', 'params': [None, 'get_block', [2500002]], 'jsonrpc': '2.0', 'id': 2}
{'method': 'call', 'params': [None, 'get_block', [2500003]], 'jsonrpc': '2.0', 'id': 2}
{'method': 'call', 'params': [None, 'get_block', [2500004]], 'jsonrpc': '2.0', 'id': 2}
{'method': 'call', 'params': [None, 'get_block', [2500005]], 'jsonrpc': '2.0', 'id': 2}
{'method': 'call', 'params': [None, 'get_block', [2500006]], 'jsonrpc': '2.0', 'id': 2}
{'method': 'call', 'params': [None, 'get_block', [2500007]], 'jsonrpc': '2.0', 'id': 2}
{'method': 'call', 'params': [None, 'get_block', [2500000]], 'jsonrpc': '2.0', 'id': 13}
{'method': 'call', 'params': [None, 'get_block', [2500003]], 'jsonrpc': '2.0', 'id': 14}
{'method': 'call', 'params': [None, 'get_block', [2500004]], 'jsonrpc': '2.0', 'id': 15}
{'method': 'call', 'params': [None, 'get_block', [2500005]], 'jsonrpc': '2.0', 'id': 16}
{'method': 'call', 'params': [None, 'get_block', [2500007]], 'jsonrpc': '2.0', 'id': 17}
{'method': 'call', 'params': [None, 'get_block', [2500008]], 'jsonrpc': '2.0', 'id': 18}
{'method': 'call', 'params': [None, 'get_block', [2500009]], 'jsonrpc': '2.0', 'id': 3}
{'method': 'call', 'params': [None, 'get_block', [2500010]], 'jsonrpc': '2.0', 'id': 3}
{'method': 'call', 'params': [None, 'get_block', [2500008]], 'jsonrpc': '2.0', 'id': 19}
{'method': 'call', 'params': [None, 'get_block', [2500009]], 'jsonrpc': '2.0', 'id': 20}
{'method': 'call', 'params': [None, 'get_block', [2500010]], 'jsonrpc': '2.0', 'id': 21}
8 of the 11 blocks are fetched twice: 2500000, 2500003, 2500004, 2500005, 2500007, 2500008, 2500009, 2500010. Those blocks contain no operations.
The reason seems to be here:
Line 463 in 78281e7
len(b.operations) == 0
, the block is treated as if it was never fetched from the chain.
# beempy --version
beempy, version 0.19.53
# python --version
Python 3.6.6
The bot created this issue to inform you that pyup.io has been set up on this repo.
Once you have closed it, the bot will open pull requests for updates as soon as they are available.
Hey Holger,
as the original author of pysteem/piston-lib and python-graphene, I am looking to cooperate with you.
How about we put our efforts with respect to python-graphene (*graphene*
modules) together and merge our improvements our improvements? I think we can both benefit from reduced code duplications and better code maintainability by moving low-level stuff to python-graphene.
What are your thoughts?
Using the following sample code
from beem.discussions import Query, Discussions_by_comments
q = Query(limit=10, start_author="jat", start_permlink="firstpost")
for h in Discussions_by_comments(q):
print(h)
I get an error UnhandledRPCError: Comment is not in account's comments
when used on Vit. I tried to give it a steem_instance=stm
even though I am using a shared instance, it still does not work.
account.history_reverse(start=start, stop=stop, only_ops=['comment'])
with start
and stop
being datetime
objects should return the all comment
operations of an account in the given time range.
account.history_reverse(start=start, stop=stop, only_ops=['comment'])
may fail with a TypeError
exception:
Traceback (most recent call last):
File "account_history_reverse.py", line 10, in <module>
for op in a.history_reverse(start=start, stop=stop, only_ops=['comment']):
File "/usr/local/lib/python3.6/site-packages/beem/account.py", line 1335, in history_reverse
while(op_est + est_diff + batch_size < first and block_date < start):
TypeError: '<' not supported between instances of 'str' and 'datetime.datetime'
block_date
is a string in this case and is compared to start
as a datetime
object.
#!/usr/bin/python
from beem.account import Account
from datetime import datetime, timedelta
from beem.utils import addTzInfo
a = Account("steemcleaners")
start = addTzInfo(datetime.utcnow()) - timedelta(days=1)
stop = addTzInfo(datetime.utcnow()) - timedelta(days=7)
for op in a.history_reverse(start=start, stop=stop, only_ops=['comment']):
print(op)
Suspicion: block_date
is converted to datetime objects in other places with formatTimeString()
. This is not the case for the failing location, h["timestamp"]
is used directly as a string.
Possible Fix:
diff --git a/beem/account.py b/beem/account.py
index b41cb58..b4ca42f 100644
--- a/beem/account.py
+++ b/beem/account.py
@@ -1331,13 +1331,13 @@ class Account(BlockchainObject):
est_diff = 0
if isinstance(start, (datetime, date, time)):
for h in self.get_account_history(op_est, 0):
- block_date = h["timestamp"]
+ block_date = formatTimeString(h["timestamp"])
while(op_est + est_diff + batch_size < first and block_date < start):
est_diff += batch_size
if op_est + est_diff > first:
est_diff = first - op_est
for h in self.get_account_history(op_est + est_diff, 0):
- block_date = h["timestamp"]
+ block_date = formatTimeString(h["timestamp"])
else:
for h in self.get_account_history(op_est, 0):
block_num = h["block"]
# beempy --version
beempy, version 0.19.32
# python --version
Python 3.6.5
blockchain.history()
and blockchain.history_reverse()
are expected to accept block numbers, transaction numbers or dates for the start
and stop
parameters and only return account operations that happend within this range for any existing Steem account:
:param int/datetime start: start number/date of transactions to
return (*optional*)
:param int/datetime stop: stop number/date of transactions to
return (*optional*)
:param bool use_block_num: if true, start and stop are block numbers,
otherwise virtual operation count numbers.
account.history()
and account.history_reverse()
with block numbers as start
and stop
parameters tries to fetch blocks with a negative block number if the account was created in the first days of Steem. The call fails with a beem.exceptions.BlockDoesNotExistsException
. Using the corresponding time stamps for start
and stop
as datetime
instances in the history()
/history_reverse()
calls give the correct results.
Picking an early created account (e.g. berniesanders
: created on '2016-03-26 08:26:21+00:00') and a random transaction (e.g. in Block 22487722):
#!/usr/bin/python
from beem.account import Account
a = Account("berniesanders")
start = 22487721
stop = 22487723
for op in a.history(start=start, stop=stop, use_block_num=True):
print(op)
or
#!/usr/bin/python
from beem.account import Account
a = Account("berniesanders")
start = 22487723
stop = 22487721
for op in a.history_reverse(start=start, stop=stop, use_block_num=True):
print(op)
Result:
Traceback (most recent call last):
File "bug_neg_blocknum.py", line 8, in <module>
for op in a.history(start=start, stop=stop, use_block_num=True):
File "/usr/local/lib/python3.6/site-packages/beem/account.py", line 1170, in history
op_est = self.estimate_virtual_op_num(start, stop_diff=1)
File "/usr/local/lib/python3.6/site-packages/beem/account.py", line 888, in estimate_virtual_op_num
created_blocknum = b.get_estimated_block_num(created, accurate=True)
File "/usr/local/lib/python3.6/site-packages/beem/blockchain.py", line 163, in get_estimated_block_num
block = Block(block_number, steem_instance=self.steem)
File "/usr/local/lib/python3.6/site-packages/beem/block.py", line 68, in __init__
steem_instance=steem_instance
File "/usr/local/lib/python3.6/site-packages/beem/blockchainobject.py", line 114, in __init__
self.refresh()
File "/usr/local/lib/python3.6/site-packages/beem/block.py", line 96, in refresh
raise BlockDoesNotExistsException(str(self.identifier))
beem.exceptions.BlockDoesNotExistsException: -17607
The cause of the error is that blockchain.get_estimated_block_num()
returns a negative block number. This function is used to look up the block number of the account creation date.
>>> b.block_time(1)
datetime.datetime(2016, 3, 24, 16, 5, tzinfo=<UTC>)
>>> b.get_estimated_block_num(addTzInfo(datetime(2016, 3, 26, 8, 26, 21)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/beem/blockchain.py", line 163, in get_estimated_block_num
block = Block(block_number, steem_instance=self.steem)
File "/usr/local/lib/python3.6/site-packages/beem/block.py", line 68, in __init__
steem_instance=steem_instance
File "/usr/local/lib/python3.6/site-packages/beem/blockchainobject.py", line 114, in __init__
self.refresh()
File "/usr/local/lib/python3.6/site-packages/beem/block.py", line 96, in refresh
raise BlockDoesNotExistsException(str(self.identifier))
beem.exceptions.BlockDoesNotExistsException: -17607
The smallest timestamp that returns a positive block number is 2016-03-26T23:06:42
, any earlier timestamp raises an exception:
>>> b.get_estimated_block_num(addTzInfo(datetime(2016, 3, 26, 23, 6, 42)))
65330
>>> b.get_estimated_block_num(addTzInfo(datetime(2016, 3, 26, 23, 6, 41)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/beem/blockchain.py", line 163, in get_estimated_block_num
block = Block(block_number, steem_instance=self.steem)
File "/usr/local/lib/python3.6/site-packages/beem/block.py", line 68, in __init__
steem_instance=steem_instance
File "/usr/local/lib/python3.6/site-packages/beem/blockchainobject.py", line 114, in __init__
self.refresh()
File "/usr/local/lib/python3.6/site-packages/beem/block.py", line 96, in refresh
raise BlockDoesNotExistsException(str(self.identifier))
beem.exceptions.BlockDoesNotExistsException: 0
# beempy --version
beempy, version 0.19.33
# python --version
Python 3.6.5
Account.history(start, stop)
with start and stop being datetime instances should return all blockchain operations from an account for the given start/stop timestamps.
Account.history(start, stop)
may be missing operations from the given time range
I know I've created a post on 2018-02-05 14:06:54, so the account history should contain at least one comment
operation on that day:
from beem.account import Account
from datetime import datetime, timedelta
from beem.utils import parse_time, addTzInfo
a = Account("stmdev")
start = addTzInfo(datetime(2018, 2, 5))
stop = addTzInfo(datetime(2018, 2, 6))
for op in a.history(start=start, stop=stop, only_ops=['comment']):
print(op['timestamp'], op['author'], op['permlink'])
The result is empty even though there were blockchain operations from this account in the given time range.
The virtual op number estimation gives wrong results in this case. I know that this comment
operation has index=2
:
for op in a.get_account_history(2, 0):
print(op['timestamp'], op['author'], op['permlink'])
2018-02-05T14:06:54 stmdev test
So a.estimate_virtual_op_num(datetime(2018, 2, 5, 14, 6, 54))
should return 2
, but it actually returns 282
:
from beem.account import Account
from datetime import datetime, timedelta
from beem.utils import parse_time, addTzInfo
a = Account("stmdev")
print(a.estimate_virtual_op_num(datetime(2018, 2, 5, 14, 6, 54)))
estimate_virtual_op_num
has a max_count
parameter that defines how many attempts beem should make before giving up. The default is 100. The limit can be disabled via max_count=-1
, so beem should do as many attempts as necessary to find the according virtual op number:
a.estimate_virtual_op_num(datetime(2018, 2, 5, 14, 6, 54), max_count=-1)
This runs in an endless loop and never returns. The virtual op number estimation does not converge. The result 282
from above is just by coincidence the result after the 100th iteration for the default max_count
until beem gives up. Printing out the current op num from the while
loop shows that this number is oscillating and not converging towards the target value.
This behavior is the same across beem-0.19.37 up to 0.19.41, so it's not introduced from the latest changes to this function.
beempy, version 0.19.41
# python --version
Python 3.6.5
Discussions.get_discussions(type, query)
can be used to retrieve any kind of discussion types
with a given query
Discussions.get_discussions(type, query)
fails with a TypeError
.
Using the provided example
from beem.discussions import Query, Discussions
query = Query(limit=51, tag="steemit")
discussions = Discussions()
count = 0
for d in discussions.get_discussions("tags", query, limit=200):
print(("%d. " % (count + 1)) + str(d))
count += 1
Result:
Traceback (most recent call last):
File "testcode.py", line 5, in <module>
for d in discussions.get_discussions("tags", query, limit=200):
File "/usr/local/lib/python3.6/site-packages/beem/discussions.py", line 121, in get_discussions
dd = Trending_tags(discussion_query, self.steem, lazy=self.lazy)
TypeError: __init__() got multiple values for argument 'lazy'
The reason is that self.steem
is a keyword argument but provided as a non-keyword argument at the position of lazy
.
Blockchain.get_transaction
should return the transaction for a given transaction id
Blockchain.get_transaction_hex
should return a hexdump of the serialized binary form of a transaction
Blockchain.get_transaction
and Blockchain.get_transaction_hex
fail on appbase nodes with Could not find method get_transaction
from beem import Steem
from beem.blockchain import Blockchain
trx_id = '6fde0190a97835ea6d9e651293e90c89911f933c'
s = Steem(node=['https://api.steemit.com'])
b = Blockchain(steem_instance=s)
print(b.get_transaction(trx_id))
from beem import Steem
from beem.blockchain import Blockchain
trx = {"ref_block_num":1097,"ref_block_prefix":2181793527,"expiration":"2016-03-24T18:00:21","operations":[{"type":"pow_operation","value":{"worker_account":"cloop3","block_id":"00000449f7860b82b4fbe2f317c670e9f01d6d9a","nonce":3899,"work":{"worker":"STM7P5TDnA87Pj9T4mf6YHrhzjC1KbPZpNxLWCcVcHxNYXakpoT4F","input":"ae8e7c677119d22385f8c48026fee7aad7bba693bf788d7f27047f40b47738c0","signature":"1f38fe9a3f9989f84bd94aa5bbc88beaf09b67f825aa4450cf5105d111149ba6db560b582c7dbb026c7fc9c2eb5051815a72b17f6896ed59d3851d9a0f9883ca7a","work":"000e7b209d58f2e64b36e9bf12b999c6c7af168cc3fc41eb7f8a4bf796c174c3"},"props":{"account_creation_fee":{"amount":"100000","precision":3,"nai":"@@000000021"},"maximum_block_size":131072,"sbd_interest_rate":1000}}}],"extensions":[],"signatures":[]}
s = Steem(node=['https://api.steemit.com'])
b = Blockchain(steem_instance=s)
print(b.get_transaction_hex(trx))
The problem with get_transaction_hex()
is a typo, the function internally calls get_transaction()
instead of get_transaction_hex()
.
get_transaction()
tries to use database_api
. However, this method is not part of database_api. According to the documentation, it's only part of condenser_api
. Changing the API to "condenser"
results in a account_history_api_plugin not enabled
Exception. This exception is also thrown with the example in the official documentation. I have no idea how to fix get_transaction()
for appbase nodes.
# python --version
Python 3.6.6
# beempy --version
beempy, version 0.19.50
blockchain.get_all_accounts(limit=5000)
should return the first 5000 Steem accounts
blockchain.get_all_accounts(limit=5000)
returns 5000 account names, however 4 of them are contained twice in the list, leaving 4996 unique account names
>>> from beem import blockchain
>>> b = Blockchain()
>>> len(list(b.get_all_accounts(limit=5000)))
5000
>>> len(set(b.get_all_accounts(limit=5000)))
4996
The reason is that the accounts are fetched in batches (default: 1000 accounts per RPC call) where the last result of the previous batch is also the first result of the next batch.
Using the testing code (see below), the program finishes and returns no results.
Using the testing code (see below), the program does not finish.
q = Query(tag='utopian-io', select_authors=["actifit"])
dd = Discussions(steem_instance=Steem(node="https://api.steemit.com")).get_discussions(discussion_type="blog", discussion_query=q, limit=10)
for d in dd:
print(d["url"])
If dd
is empty in https://github.com/holgern/beem/blob/master/beem/discussions.py#L154 , then the while cycle will never end.
Running something like this gives me a weight of -100%
print(comment.upvote(weight=99.9))
If I changed the weight to 100 or above it votes 100%.
And if I set the default with beempy it has no impact. It defaults to 100%.
default_vote_weight | 99.9
I'm running beem 0.19.23
Blockchain.stream/blocks(start, stop, only_ops=True)
should return all ops in the given block range. Additionally using threading=True
should eventually speed things up.
Blockchain.stream/blocks(start, stop, only_ops=True, threading=True)
prints errors
int() argument must be a string, a bytes-like object or a number, not 'NoneType'
and never completes.
from beem.blockchain import Blockchain
b = Blockchain()
for op in b.blocks(start=25000000, stop=25000010, only_ops=True,
threading=True):
continue
Output:
int() argument must be a string, a bytes-like object or a number, not 'NoneType'
int() argument must be a string, a bytes-like object or a number, not 'NoneType'
int() argument must be a string, a bytes-like object or a number, not 'NoneType'
int() argument must be a string, a bytes-like object or a number, not 'NoneType'
int() argument must be a string, a bytes-like object or a number, not 'NoneType'
int() argument must be a string, a bytes-like object or a number, not 'NoneType'
...
# beempy --version
beempy, version 0.20.12
# python --version
Python 3.6.6
Does beem provide api to get the number of pending claimed accounts?
Thanks in advance.
This is a very useful function from, Steem-python for getting multiple but not all witnesses in a single RPC call. Would be great to see it added to Beem.
Project Information
Repository
https://github.com/holgern/beem
Project Name - BEEM APP
Expected Behavior
SUPPORT OF USER AVATAR (User should be able to Upload AVATAR when Updating Status).
Actual Behavior
NOT SUPPORTING USERS AVATAR (Application fail to Upload Avatar, thereby denying user of providing an Image for other users to see).
How To Reproduce;
Download and Install Beem-Chat App from Google play store
Open the application to create an account or use an existing account.
Click the three dots on the right upper part and choose Change status from the listed menu.
Click on the avatar icon to upload an image, then it fails to upload the avatar.
Recording of the Bug
https://www.youtube.com/watch?v=P4r4AZaJvfk
Whenever i use the Postmethod of beem it sets the first tag wrong. The post always hast the first letter of the first tag as the first tag. Then it goes an as expected.
For example if i use tags="steem beem foo bar" the tags will be: s steem beem foo bar
if i use tags = "foo bar" it will be: f foo bar and so on
Haven't found any info about that issue so far, is the problem on my side?
I had the issue with 20.3 and also after i updated to 20.5
Edit: Also my posts dont show up in any category on steem.
Thanks for the GetWitnesses() function.
It works great on Steem, but on Vit I noticed it throws the following error.
Invalid cast from array_type to string
{"type":"array_type"}
th_a variant.cpp:478 as_string
I tried just using one witness (in a list) and a list of them, both fail with a similar error.
As per the steem documentation of the API method (see https://developers.steem.io/apidefinitions/#tags_api.get_discussions_by_author_before_date, the input parameters should be:
The correct parameters should be described in the docstring of the method and passed in the get_discussions
method of Discussions class.
Although the method definition has the correct parameters, the docstring describes the parameters as instance of Query class. https://github.com/holgern/beem/blob/master/beem/discussions.py#L205
Furthermore, incorrect query parameter is passed in get_discussions
method. https://github.com/holgern/beem/blob/master/beem/discussions.py#L113
The Discussions_by_author_before_date
method can't get parameters from the instance of Query because the class does not have all needed parameters such as before_date
and author
.
can i join? i have idea for this logo )
SteemConnect TransactionBuilder example from
Line 57 in a14aee9
'https://v2.steemconnect.com/sign/transfer?from=test&to=test1&amount=1.000+STEEM&memo=test'
Apart from minor syntax errors in the example, the output string is empty:
Output:
''
Applying syntax error fixes to the example code:
--- a/beem/steemconnect.py
+++ b/beem/steemconnect.py
@@ -60,13 +60,14 @@ class SteemConnect(object):
from beem.steemconnect import SteemConnect
from pprint import pprint
stm = Steem()
+ sc2 = SteemConnect(steem_instance=stm)
tx = TransactionBuilder(steem_instance=stm)
op = operations.Transfer(**{"from": 'test',
"to": 'test1',
"amount": '1.000 STEEM',
"memo": 'test'})
tx.appendOps(op)
- pprint(sc2.url_from_tx(tx)
+ pprint(sc2.url_from_tx(tx))
.. testcode::
This gives the following sample script:
from beem import Steem
from beem.transactionbuilder import TransactionBuilder
from beembase import operations
from beem.steemconnect import SteemConnect
from pprint import pprint
stm = Steem()
sc2 = SteemConnect(steem_instance=stm)
tx = TransactionBuilder(steem_instance=stm)
op = operations.Transfer(**{"from": 'test',
"to": 'test1',
"amount": '1.000 STEEM',
"memo": 'test'})
tx.appendOps(op)
pprint(sc2.url_from_tx(tx))
with output:
''
Adding a print(tx)
before the pprint
makes it work?!
from beem import Steem
from beem.transactionbuilder import TransactionBuilder
from beembase import operations
from beem.steemconnect import SteemConnect
from pprint import pprint
stm = Steem()
sc2 = SteemConnect(steem_instance=stm)
tx = TransactionBuilder(steem_instance=stm)
op = operations.Transfer(**{"from": 'test',
"to": 'test1',
"amount": '1.000 STEEM',
"memo": 'test'})
tx.appendOps(op)
print(tx)
pprint(sc2.url_from_tx(tx))
Output:
{'expiration': '2018-07-08T08:49:12', 'ref_block_num': 5087, 'ref_block_prefix': 2415621679, 'operations': [['transfer', {'from': 'test', 'to': 'test1', 'amount': '1.000 STEEM', 'memo': 'test'}]], 'extensions': [], 'signatures': []}
'https://v2.steemconnect.com/sign/transfer?from=test&to=test1&amount=1.000+STEEM&memo=test'
# beempy --version
beempy, version 0.19.46
# python --version
Python 3.6.5
blockchain.blocks(start=start, stop=stop, threading=True)
should return all requested blocks.
blockchain.blocks(start=start, stop=stop, threading=True)
may raise a RuntimeError
due to a race condition when a dictionary is changed while being iterated on. The streaming of the blocks stops at non-deterministic block numbers.
Traceback (most recent call last):
File "block_race_condition.py", line 9, in <module>
for block in b.blocks(start=10000, stop=20000, threading=True, thread_num=8):
File "/usr/local/lib/python3.6/site-packages/beem/blockchain.py", line 241, in blocks
results = [r.result() for r in as_completed(futures)]
File "/usr/local/lib/python3.6/site-packages/beem/blockchain.py", line 241, in <listcomp>
results = [r.result() for r in as_completed(futures)]
File "/usr/local/lib/python3.6/concurrent/futures/_base.py", line 425, in result
return self.__get_result()
File "/usr/local/lib/python3.6/concurrent/futures/_base.py", line 384, in __get_result
raise self._exception
File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.6/site-packages/beem/block.py", line 68, in __init__
steem_instance=steem_instance
File "/usr/local/lib/python3.6/site-packages/beem/blockchainobject.py", line 138, in __init__
self.cache()
File "/usr/local/lib/python3.6/site-packages/beem/blockchainobject.py", line 163, in cache
BlockchainObject._cache[self.get(self.id_item)] = self
File "/usr/local/lib/python3.6/site-packages/beem/blockchainobject.py", line 33, in __setitem__
self.clear_expired_items()
File "/usr/local/lib/python3.6/site-packages/beem/blockchainobject.py", line 48, in clear_expired_items
for key in self.keys():
RuntimeError: dictionary changed size during iteration
The corresponding code part is in
Line 47 in bd8cf74
self.keys()
changes while being iterated on.
from beem.blockchain import Blockchain
from beem import Steem
import sys
b = Blockchain()
for block in b.blocks(start=10000, stop=20000, threading=True, thread_num=8):
sys.stdout.write("%s (%s)\r" % (block['id'], block['timestamp']))
This code sometimes results in the RuntimeError
above. The block number at which the error occurs changes and it may need dozens of runs until it actually fails. However, the problem can be articifially amplified by adding a time.sleep(1)
into the corresponding for key in self.keys():
loop:
diff --git a/beem/blockchainobject.py b/beem/blockchainobject.py
index 03d22de..09d56ca 100644
--- a/beem/blockchainobject.py
+++ b/beem/blockchainobject.py
@@ -9,6 +9,7 @@ from beemgraphenebase.py23 import bytes_types, integer_types, string_types, text
from beem.instance import shared_steem_instance
from datetime import datetime, timedelta
import json
+import time
@python_2_unicode_compatible
@@ -46,6 +47,7 @@ class ObjectCache(dict):
keys = []
for key in self.keys():
keys.append(key)
+ time.sleep(1)
for key in keys:
value = dict.__getitem__(self, key)
if datetime.utcnow() >= value["expires"]:
With this change, the library spends significant amounts of time in the iteration loop on self.keys()
. Technically it does not make a difference apart from being terribly slow now. With this in place, the above exception can be triggered with the given code sample within seconds.
The exception is not raised when multi-threading is disabled via threading=False
. To my understanding, multiple threads are accessing the same ObjectCache()
instance. Disabling the cache via the use_cache=False
flag in the BlockchainObject
constructor defaults for testing purposes did not work:
Traceback (most recent call last):
File "block_race_condition.py", line 10, in <module>
sys.stdout.write("%s (%s)\r" % (block['id'], block['timestamp']))
File "/usr/local/lib/python3.6/site-packages/beem/blockchainobject.py", line 173, in __getitem__
self.refresh()
File "/usr/local/lib/python3.6/site-packages/beem/block.py", line 76, in refresh
self.identifier = int(self.identifier)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
Using a copy of self.keys()
via for key in self.keys()[:]:
will only shift the problem, because two instances will still try to access/delete the same cache entries independently.
# beempy --version
beempy, version 0.19.32
# python --version
Python 3.6.5
Signing operations that work correctly when invoked from a script running in the Python3 interpreter throw a beem.exceptions.InvalidWifError when the script is run in the Python 2 interpreter.
See this link for a more complete description:
https://steemit.com/utopian-io/@mattockfs/signing-python-2-beem-scripts-stopped-working
Account.get_tags_used_by_author
should return a list of tags or an empty list
Account.get_tags_used_by_author
fails with an RPC error on appbase nodes:
>>> a.get_tags_used_by_author()
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/beemapi/steemnoderpc.py", line 64, in rpcexec
reply = super(SteemNodeRPC, self).rpcexec(payload)
File "/usr/local/lib/python3.6/site-packages/beemapi/graphenerpc.py", line 409, in rpcexec
raise RPCError(ret['error']['message'])
beemapi.exceptions.RPCError: Assert Exception:acnt != nullptr: Author not found
from beem.account import Account
from beem import Steem
s = Steem(node=['https://api.steemit.com'])
a = Account('crokkon', steem_instance=s)
print(a.get_tags_used_by_author())
get_tags_used_by_author
requires an argument author
, but currently gets the argument account
:
Line 1144 in 243bb99
# beempy --version
beempy, version 0.19.50
# python --version
Python 3.6.6
discussions.Replies_by_last_update()
should return a list of the last replies to posts/comments from a given author
discussions.Replies_by_last_update()
cannot be used to get a list of the last replies to posts/comments from a given author. The list of Comment
instances returned are not replies to the given author.
from beem.discussions import Replies_by_last_update, Query
query = {'limit': 10, 'start_parent_author': 'stmdev',
'start_permlink': None, 'start_author': None}
replies = Replies_by_last_update(query)
for reply in replies:
print(reply)
Output:
<Comment @bonanza-kreep/agrotechfarm-presents-a-cutting-edge-smart-farming-solution>
<Comment @pizzaboy77/song-challenge-tag-1-30>
<Comment @w6lk3r/k-2018-6-2-11-21-57>
<Comment @ram2144/3wfp2n-punch>
<Comment @statsexpert/daily-top-posts-in-category-nature-on-2018-07-17>
<Comment @carlsmart303/9y5xb-travel>
<Comment @sahelmakrani/saud-binmazi>
<Comment @revia/kisah-seorang-petani-6851709cbae9b>
<Comment @fingersik/decentralizationtotherescuedecenternetthevisionpt1of6-qbd77zigc6>
<Comment @gaiablock/an-appetizer-of-cpos-consensus-algorithm-by-gaiaworld-gamechain>
The reason is that the start_parent_author
parameter is not propagated to the RPC call:
https://developers.steem.io/apidefinitions/#tags_api.get_replies_by_last_update
I have been using Beem for a little while. I installed Steemmonsters and use it regularly, and I also have a tool to crosspost from Steem to Whaleshares using Beem, but today I tried to use the Account module to do some tests and it just refused with an error:
Traceback (most recent call last):
File ".\beemtest.py", line 1, in <module>
from beem import Account
ImportError: cannot import name 'Account' from 'beem' (C:\ProgramData\Miniconda3\lib\site-packages\beem\__init__.py)
Did I do something wrong? My code is simply
from beem import Account
account = Account("cryptosharon")
print(account.balances)
I assume it was an installation error at some point. Maybe Miniconda3 cannot handle certain modules, or maybe it was a corrupted or incomplete installation (or maybe it was an update on Beem that removed Account or changed its name?)
I have an interesting problem which should be solvable with Beem, but which I can't quite seem to figure out how to put into the context of the module UI.
Here's my problem:
I have a list of permlinks and authors, and I want to walk this list and accumulate certain post attributes which they have.
I've been using SteamData to acquire slices of voting data and account names, and that works just fine โ but once I have a list of specifics to investigate further, it's very difficult to get a MongoDB query that runs in a reasonable time which is efficient for pulling back a long list of specific items.
This seems like something that is tailor-made for Beem.
Unfortunately, I can't figure out from the documentation as it stands how one would go about simply formulating that function or method call. It's fairly easy to watch the blockchain for specific changes in a streaming way, but it is nontrivial to query the blockchain for specific information.
Am I just missing something obvious, or is that functionality not implemented yet, or am I trying to use the wrong tool for the wrong job?
Hello i went through your project and i want to say it is very nice. However i noticed you are missing out some important details like gaq, about us and privacy policy which users will be looking forward too. If you dont mind i can write that for you
contact me
email [email protected]
steemit.com/@ewuoso
I'm setting up beem in a new server and wanted to install it, so I tried with pip, but the same error as on Windows appears (scrypt is not very good at being installed from pip). I installed conda then did conda install -c conda-forge beem
, and it went alright. But now if I try to import it into my script, I get the error "ImportError: No module named 'beem'" even though it's in the /bin as "beempy".
If providing a memo key through steem instance and transferring money with a memo beginning with '#' the transfer is sent and every seems fine. But decrypting the message is not possible. Steemit.com would show 'invalid memo' and beem throws an exeption like this:
print(m.decrypt(memo=memo))
File "E:\ProgramData\Anaconda3\lib\site-packages\beem\memo.py", line 260, in decrypt
message
File "E:\ProgramData\Anaconda3\lib\site-packages\beembase\memo.py", line 228, in decode_memo
message = aes.decrypt(unhexlify(py23_bytes(message, 'ascii')))
File "E:\ProgramData\Anaconda3\lib\site-packages\Cryptodome\Cipher\_mode_cbc.py", line 210, in decrypt
raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size)
ValueError: Data must be padded to 16 byte boundary in CBC mode
The URL created from a transaction via steemconnect.url_from_tx()
should be able to create the according transaction via SteemConnect.
Parts of the JSON values are wrapped in single quotes (e.g. 'value'
) instead of double quotes (e.g. "value"
), leading to JSON parsing errors with the created steemconnect link
from beem import Steem
from beem.steemconnect import SteemConnect
s = Steem(nobroadcast=True, unsigned=True)
sc = SteemConnect(steem_instance=s)
tx = s.custom_json("123", {'field1': 'data1', 'field2': 'data2'}, required_posting_auths=["stmdev"])
print(sc.url_from_tx(tx))
Result:
https://v2.steemconnect.com/sign/custom_json?required_auths=%5B%5D&required_posting_auths=%5B%27stmdev%27%5D&id=123&json=%7B%22field1%22%3A+%22data1%22%2C+%22field2%22%3A+%22data2%22%7D
Note the %27
='
around stmdev
, but %22
="
around the actual payload.
By modifying the URL to replace all %27
with %22
the URL works:
https://steemconnect.com/sign/custom_json?required_auths=%5B%5D&required_posting_auths=%5B%22stmdev%22%5D&id=123&json=%7B%22field1%22%3A+%22data1%22%2C+%22field2%22%3A+%22data2%22%7D
gregory-f from steemconnect confirmed that the "pure JSON" / SteemConnect expects double quotes.
The Signed_Transaction
class should accept existing blockchain transactions, for example to determine the original signer.
Signed_Transaction
gets along with blockchain transaction from non-appbase nodes, but fails with appbase transactions if those contain a comment_options
operation with beneficiaries. The constructor fails with Exception: Unknown CommentOptionExtension
from beem import Steem
from beem.nodelist import NodeList
from beem.blockchain import Blockchain
from beembase.signedtransactions import Signed_Transaction
s = Steem(node=NodeList().get_nodes(appbase=True, normal=False))
b = Blockchain(steem_instance=s)
for block in b.blocks(start=25304468, stop=25304468):
for trx in block.transactions:
try:
st = Signed_Transaction(trx.copy())
except Exception:
print(trx)
raise
Output:
{'transaction_id': '4c1d57de6cfeb0966c2e08da85822483c4af37d7', 'ref_block_num': 7551, 'ref_block_prefix': 107790536, 'expiration': '2018-08-23T00:11:06', 'operations': [{'type': 'comment_operation', 'value': {'parent_author': '', 'parent_permlink': 'ifttt', 'author': 'buffalo-goku', 'permlink': 'toincreaseamericasproductivitybanthishttpstcoivgi8aul1n-efyvj7avgx', 'title': "To Increase America's Productivity Ban This... https://t.co/ivgi8aUL1N", 'body': '<blockquote class="twitter-tweet"><p lang="en" dir="ltr">To Increase America’s Productivity Ban This… <a href="https://t.co/ivgi8aUL1N" target="_blank">https://t.co/ivgi8aUL1N</a></p>โ Buffalo_Goku๐ (@F_C_J_R) <a href="https://twitter.com/F_C_J_R/status/914347700178518016?ref_src=twsrc%5Etfw" target="_blank">October 1, 2017</a>\n</blockquote>\n<br />\nfrom Twitter <a href="https://twitter.com/F_C_J_R" target="_blank">https://twitter.com/F_C_J_R</a><br /><br />\nOctober 01, 2017 at 12:34AM<br />\nvia <a href="http://ift.tt/18ufGjY" target="_blank">IFTTT</a><br /><center><hr/><em>Posted from my blog with <a href=\'https://wordpress.org/plugins/steempress/\'>SteemPress</a> : https://nopoliticalcorrectnesshere.com/wp/2017/10/01/to-increase-americas-productivity-ban-this-13/</em><hr/></center>', 'json_metadata': '{"community":"steempress","app":"steempress/1.4","image":[""],"tags":["ifttt","news","nwo","politics","twitter"],"original_link":"https://nopoliticalcorrectnesshere.com/wp/2017/10/01/to-increase-americas-productivity-ban-this-13/"}'}}, {'type': 'comment_options_operation', 'value': {'author': 'buffalo-goku', 'permlink': 'toincreaseamericasproductivitybanthishttpstcoivgi8aul1n-efyvj7avgx', 'max_accepted_payout': {'amount': '1000000000', 'precision': 3, 'nai': '@@000000013'}, 'percent_steem_dollars': 10000, 'allow_votes': True, 'allow_curation_rewards': True, 'extensions': [{'type': 'comment_payout_beneficiaries', 'value': {'beneficiaries': [{'account': 'steempress', 'weight': 1500}]}}]}}, {'type': 'vote_operation', 'value': {'voter': 'buffalo-goku', 'author': 'buffalo-goku', 'permlink': 'toincreaseamericasproductivitybanthishttpstcoivgi8aul1n-efyvj7avgx', 'weight': 10000}}], 'extensions': [], 'signatures': ['203a68c042cddd1b93dd4792893b66f31880c8d410643b46ce43fa4d674012a32b4e670185dcb9c1c5db90ceddb74ecd0046d9bfdf5c0ebde962a6e267f35c6a04'], 'block_num': 25304468, 'transaction_num': 3}
Traceback (most recent call last):
File "bug_benef.py", line 12, in <module>
st = Signed_Transaction(trx.copy())
File "/usr/local/lib/python3.6/site-packages/beembase/signedtransactions.py", line 30, in __init__
super(Signed_Transaction, self).__init__(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/beemgraphenebase/signedtransactions.py", line 66, in __init__
kwargs['operations'] = Array([opklass(a) for a in kwargs["operations"]])
File "/usr/local/lib/python3.6/site-packages/beemgraphenebase/signedtransactions.py", line 66, in <listcomp>
kwargs['operations'] = Array([opklass(a) for a in kwargs["operations"]])
File "/usr/local/lib/python3.6/site-packages/beembase/objects.py", line 79, in __init__
super(Operation, self).__init__(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/beemgraphenebase/objects.py", line 54, in __init__
self.op = klass(op["value"])
File "/usr/local/lib/python3.6/site-packages/beembase/operations.py", line 364, in __init__
extensions = Array([CommentOptionExtensions(o) for o in kwargs["extensions"]])
File "/usr/local/lib/python3.6/site-packages/beembase/operations.py", line 364, in <listcomp>
extensions = Array([CommentOptionExtensions(o) for o in kwargs["extensions"]])
File "/usr/local/lib/python3.6/site-packages/beembase/objects.py", line 268, in __init__
raise Exception("Unknown CommentOptionExtension")
Exception: Unknown CommentOptionExtension
Changing the nodelist to non-appbase (appbase=False, normal=True
) gives no output as expected. Changing the block number to 25304469, containing a comment_options
operation without beneficiaries, works for both appbase and non-appbase.
It seems Signed_Transaction
doesn't get along with the additional appbase type
/value
pair in extensions
:
'extensions': [{
'type': 'comment_payout_beneficiaries',
'value': {
'beneficiaries': [
{'account': 'steempress', 'weight': 1500}
]
}]
# python --version
Python 3.6.6
# beempy --version
beempy, version 0.19.54
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.