def test_account(self): stm = self.bts account = self.account Account("creabot", crea_instance=stm) with self.assertRaises(exceptions.AccountDoesNotExistsException): Account("DoesNotExistsXXX", crea_instance=stm) # asset = Asset("1.3.0") # symbol = asset["symbol"] self.assertEqual(account.name, "creabot") self.assertEqual(account["name"], account.name) self.assertIsInstance(account.get_balance("available", "CBD"), Amount) account.print_info() # self.assertIsInstance(account.balance({"symbol": symbol}), Amount) self.assertIsInstance(account.available_balances, list) self.assertTrue(account.virtual_op_count() > 0) # BlockchainObjects method account.cached = False self.assertTrue(list(account.items())) account.cached = False self.assertIn("id", account) account.cached = False # self.assertEqual(account["id"], "1.2.1") self.assertEqual(str(account), "<Account creabot>") self.assertIsInstance(Account(account), Account)
def test_Account(self): with self.assertRaises( exceptions.AccountDoesNotExistsException ): Account("FOObarNonExisting") c = Account("test") self.assertEqual(c["name"], "test") self.assertIsInstance(c, Account)
def setUpClass(cls): nodelist = NodeList() nodelist.update_nodes(crea_instance=Crea(node=nodelist.get_nodes(exclude_limited=False), num_retries=10)) cls.bts = Crea( node=nodelist.get_nodes(exclude_limited=True), nobroadcast=True, keys={"active": wif}, num_retries=10 ) # from getpass import getpass # self.bts.wallet.unlock(getpass()) set_shared_crea_instance(cls.bts) cls.bts.set_default_account("test") acc = Account("holger80", crea_instance=cls.bts) n_votes = 0 index = 0 while n_votes == 0: comment = acc.get_feed(limit=30)[::-1][index] votes = comment.get_votes() n_votes = len(votes) index += 1 last_vote = votes[0] cls.authorpermvoter = construct_authorpermvoter(last_vote['author'], last_vote['permlink'], last_vote["voter"]) [author, permlink, voter] = resolve_authorpermvoter(cls.authorpermvoter) cls.author = author cls.permlink = permlink cls.voter = voter cls.authorperm = construct_authorperm(author, permlink)
def setUpClass(cls): nodelist = NodeList() nodelist.update_nodes(crea_instance=Crea( node=nodelist.get_nodes(exclude_limited=False), num_retries=10)) node_list = nodelist.get_nodes(exclude_limited=True) cls.bts = Crea(node=node_list, use_condenser=True, nobroadcast=True, unsigned=True, keys={"active": wif}, num_retries=10) cls.creait = Crea(node="https://nodes.creary.net", nobroadcast=True, unsigned=True, keys={"active": wif}, num_retries=10) acc = Account("holger80", crea_instance=cls.bts) comment = acc.get_feed(limit=20)[-1] cls.authorperm = comment.authorperm [author, permlink] = resolve_authorperm(cls.authorperm) cls.author = author cls.permlink = permlink cls.category = comment.category cls.title = comment.title
def profiling(name_list): stm = Crea() set_shared_crea_instance(stm) del stm print("start") for name in name_list: print("account: %s" % (name)) acc = Account(name) max_index = acc.virtual_op_count() print(max_index) stopTime = datetime(2018, 4, 22, 0, 0, 0) hist_elem = None for h in acc.history_reverse(stop=stopTime): hist_elem = h print(hist_elem) print("blockchain") blockchain_object = Blockchain() current_num = blockchain_object.get_current_block_num() startBlockNumber = current_num - 20 endBlockNumber = current_num block_elem = None for o in blockchain_object.stream(start=startBlockNumber, stop=endBlockNumber): print("block %d" % (o["block_num"])) block_elem = o print(block_elem)
def test_estimate_virtual_op_num(self): stm = self.bts account = Account("gtg", crea_instance=stm) block_num = 21248120 block = Block(block_num, crea_instance=stm) op_num1 = account.estimate_virtual_op_num(block.time(), stop_diff=1, max_count=100) op_num2 = account.estimate_virtual_op_num(block_num, stop_diff=1, max_count=100) op_num3 = account.estimate_virtual_op_num(block_num, stop_diff=100, max_count=100) op_num4 = account.estimate_virtual_op_num(block_num, stop_diff=0.00001, max_count=100) self.assertTrue(abs(op_num1 - op_num2) < 2) self.assertTrue(abs(op_num1 - op_num4) < 2) self.assertTrue(abs(op_num1 - op_num3) < 200) block_diff1 = 0 block_diff2 = 0 for h in account.get_account_history(op_num4 - 1, 0): block_diff1 = (block_num - h["block"]) for h in account.get_account_history(op_num4 + 1, 0): block_diff2 = (block_num - h["block"]) self.assertTrue(block_diff1 > 0) self.assertTrue(block_diff2 <= 0)
def test_approvewitness(self): bts = self.bts w = Account("crea", crea_instance=bts) tx = w.approvewitness("crea1") self.assertEqual((tx["operations"][0][0]), "account_witness_vote") op = tx["operations"][0][1] self.assertIn("crea1", op["witness"])
def sign(self, account=None, **kwargs): """ Sign a message with an account's memo key :param str account: (optional) the account that owns the bet (defaults to ``default_account``) :returns: the signed message encapsulated in a known format """ if not account: if "default_account" in config: account = config["default_account"] if not account: raise ValueError("You need to provide an account") # Data for message account = Account(account, crea_instance=self.crea) info = self.crea.info() meta = dict(timestamp=info["time"], block=info["head_block_number"], memokey=account["memo_key"], account=account["name"]) # wif key wif = self.crea.wallet.getPrivateKeyForPublicKey(account["memo_key"]) # signature message = self.message.strip() signature = hexlify( sign_message(SIGNED_MESSAGE_META.format(**locals()), wif)).decode("ascii") message = self.message return SIGNED_MESSAGE_ENCAPSULATED.format(MESSAGE_SPLIT=MESSAGE_SPLIT, **locals())
def test_follow_posting_key(self): nodelist = NodeList() stm = Crea(node=self.nodes, keys=[self.posting_key], nobroadcast=True, expiration=120, num_retries=10) account = Account("crea", crea_instance=stm) account.follow("crea1")
def verify(self, **kwargs): """ Verify a message with an account's memo key :param str account: (optional) the account that owns the bet (defaults to ``default_account``) :returns: True if the message is verified successfully :raises InvalidMessageSignature: if the signature is not ok """ # Split message into its parts parts = re.split("|".join(MESSAGE_SPLIT), self.message) parts = [x for x in parts if x.strip()] if not len(parts) > 2: raise AssertionError("Incorrect number of message parts") message = parts[0].strip() signature = parts[2].strip() # Parse the meta data meta = dict(re.findall(r'(\S+)=(.*)', parts[1])) # Ensure we have all the data in meta if "account" not in meta: raise AssertionError() if "memokey" not in meta: raise AssertionError() if "block" not in meta: raise AssertionError() if "timestamp" not in meta: raise AssertionError() # Load account from blockchain account = Account(meta.get("account"), crea_instance=self.crea) # Test if memo key is the same as on the blockchain if not account["memo_key"] == meta["memokey"]: log.error("Memo Key of account {} on the Blockchain".format( account["name"]) + "differs from memo key in the message: {} != {}".format( account["memo_key"], meta["memokey"])) # Reformat message message = SIGNED_MESSAGE_META.format(**locals()) # Verify Signature pubkey = verify_message(message, unhexlify(signature)) # Verify pubky pk = PublicKey(hexlify(pubkey).decode("ascii")) if format(pk, self.crea.prefix) != meta["memokey"]: raise InvalidMessageSignature return True
def test_account(self, node_param): if node_param == "instance": set_shared_crea_instance(self.bts) acc = Account("test") self.assertIn(acc.crea.rpc.url, self.urls) self.assertIn(acc["balance"].crea.rpc.url, self.urls) with self.assertRaises(RPCConnection): Account("test", crea_instance=Crea(node="https://abc.d", autoconnect=False, num_retries=1)) else: set_shared_crea_instance( Crea(node="https://abc.d", autoconnect=False, num_retries=1)) stm = self.bts acc = Account("test", crea_instance=stm) self.assertIn(acc.crea.rpc.url, self.urls) self.assertIn(acc["balance"].crea.rpc.url, self.urls) with self.assertRaises(RPCConnection): Account("test")
def setUpClass(cls): nodelist = NodeList() nodelist.update_nodes(crea_instance=Crea( node=nodelist.get_nodes(exclude_limited=False), num_retries=10)) cls.bts = Crea(node=nodelist.get_nodes(exclude_limited=True), nobroadcast=True, unsigned=True, data_refresh_time_seconds=900, num_retries=10) cls.account = Account("test", full=True, crea_instance=cls.bts)
def test_blog_history(self): account = Account("holger80", crea_instance=self.bts) posts = [] for p in account.blog_history(limit=5): if p["author"] != account["name"]: continue posts.append(p) self.assertTrue(len(posts) >= 1) self.assertEqual(posts[0]["author"], account["name"]) self.assertTrue(posts[0].is_main_post()) self.assertTrue(posts[0].depth == 0)
def test_update_memo_key(self): bts = self.bts bts.wallet.unlock("123") self.assertEqual(bts.prefix, "STX") acc = Account("crea", crea_instance=bts) tx = acc.update_memo_key( "STX55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n") self.assertEqual((tx["operations"][0][0]), "account_update") op = tx["operations"][0][1] self.assertEqual( op["memo_key"], "STX55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n")
def test_history_votes(self): stm = self.bts account = Account("gtg", crea_instance=stm) utc = pytz.timezone('UTC') limit_time = utc.localize(datetime.utcnow()) - timedelta(days=2) votes_list = [] for v in account.history(start=limit_time, only_ops=["vote"]): votes_list.append(v) start_num = votes_list[0]["block"] votes_list2 = [] for v in account.history(start=start_num, only_ops=["vote"]): votes_list2.append(v) self.assertTrue(abs(len(votes_list) - len(votes_list2)) < 2)
def test_finalizeOps(self): bts = self.bts tx1 = bts.new_tx() tx2 = bts.new_tx() acc = Account("crea", crea_instance=bts) acc.transfer("crea1", 1, "CREA", append_to=tx1) acc.transfer("crea1", 2, "CREA", append_to=tx2) acc.transfer("crea1", 3, "CREA", append_to=tx1) tx1 = tx1.json() tx2 = tx2.json() ops1 = tx1["operations"] ops2 = tx2["operations"] self.assertEqual(len(ops1), 2) self.assertEqual(len(ops2), 1)
def setUpClass(cls): nodelist = NodeList() nodelist.update_nodes(crea_instance=Crea( node=nodelist.get_nodes(exclude_limited=False), num_retries=10)) node_list = nodelist.get_nodes(exclude_limited=True) cls.bts = Crea( node=node_list, nobroadcast=True, bundle=False, unsigned=True, # Overwrite wallet to use this list of wifs only keys={"active": wif}, num_retries=10) cls.account = Account("creabot", crea_instance=cls.bts) set_shared_crea_instance(cls.bts)
def test_history_reverse2(self): stm = self.bts account = Account("creabot", crea_instance=stm) h_list = [] max_index = account.virtual_op_count() for h in account.history_reverse(start=max_index, stop=max_index - 4, use_block_num=False, batch_size=2, raw_output=False): h_list.append(h) self.assertEqual(len(h_list), 5) for i in range(1, 5): self.assertEqual(h_list[i]["index"] - h_list[i - 1]["index"], -1) h_list = [] for h in account.history_reverse(start=max_index, stop=max_index - 4, use_block_num=False, batch_size=6, raw_output=False): h_list.append(h) self.assertEqual(len(h_list), 5) for i in range(1, 5): self.assertEqual(h_list[i]["index"] - h_list[i - 1]["index"], -1) h_list = [] for h in account.history_reverse(start=max_index, stop=max_index - 4, use_block_num=False, batch_size=6, raw_output=True): h_list.append(h) self.assertEqual(len(h_list), 5) for i in range(1, 5): self.assertEqual(h_list[i][0] - h_list[i - 1][0], -1) h_list = [] for h in account.history_reverse(start=max_index, stop=max_index - 4, use_block_num=False, batch_size=2, raw_output=True): h_list.append(h) self.assertEqual(len(h_list), 5) for i in range(1, 5): self.assertEqual(h_list[i][0] - h_list[i - 1][0], -1)
def test_transfer(self): bts = self.bts bts.nobroadcast = False bts.wallet.unlock("123") # bts.wallet.addPrivateKey(self.active_key) # bts.prefix ="STX" acc = Account("crea", crea_instance=bts) tx = acc.transfer("crea1", 1.33, "CBD", memo="Foobar") self.assertEqual(tx["operations"][0][0], "transfer") self.assertEqual(len(tx['signatures']), 1) op = tx["operations"][0][1] self.assertIn("memo", op) self.assertEqual(op["from"], "crea") self.assertEqual(op["to"], "crea1") amount = Amount(op["amount"], crea_instance=bts) self.assertEqual(float(amount), 1.33) bts.nobroadcast = True
def test_verifyAuthority(self): stm = self.bts stm.wallet.unlock("123") tx = TransactionBuilder(use_condenser_api=True, crea_instance=stm) tx.appendOps( Transfer( **{ "from": "crea", "to": "crea1", "amount": Amount("1.300 CBD", crea_instance=stm), "memo": "Foobar" })) account = Account("crea", crea_instance=stm) tx.appendSigner(account, "active") self.assertTrue(len(tx.wifs) > 0) tx.sign() tx.verify_authority() self.assertTrue(len(tx["signatures"]) > 0)
def test_account_by_pub(self): stm = self.stm self.wallet.crea = stm self.wallet.unlock(pwd="TestingOneTwoThree") acc = Account("gtg") pub = acc["owner"]["key_auths"][0][0] acc_by_pub = self.wallet.getAccount(pub) self.assertEqual("gtg", acc_by_pub["name"]) gen = self.wallet.getAccountsFromPublicKey(pub) acc_by_pub_list = [] for a in gen: acc_by_pub_list.append(a) self.assertEqual("gtg", acc_by_pub_list[0]) gen = self.wallet.getAllAccounts(pub) acc_by_pub_list = [] for a in gen: acc_by_pub_list.append(a) self.assertEqual("gtg", acc_by_pub_list[0]["name"]) self.assertEqual(pub, acc_by_pub_list[0]["pubkey"])
def test_disallow(self): bts = self.bts acc = Account("crea", crea_instance=bts) if sys.version > '3': _assertRaisesRegex = self.assertRaisesRegex else: _assertRaisesRegex = self.assertRaisesRegexp with _assertRaisesRegex(ValueError, ".*Changes nothing.*"): acc.disallow( "STX55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", weight=1, threshold=1, permission="active") with _assertRaisesRegex(ValueError, ".*Changes nothing!.*"): acc.disallow( "STX6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", weight=1, threshold=1, permission="active")
def setUpClass(cls): cls.nodelist = NodeList() cls.nodelist.update_nodes(crea_instance=Crea( node=cls.nodelist.get_nodes( exclude_limited=False), num_retries=10)) stm = Crea(node=cls.nodelist.get_nodes()) stm.config.refreshBackup() stm.set_default_nodes(["xyz"]) del stm cls.urls = cls.nodelist.get_nodes(exclude_limited=True) cls.bts = Crea(node=cls.urls, nobroadcast=True, num_retries=10) set_shared_crea_instance(cls.bts) acc = Account("holger80", crea_instance=cls.bts) comment = acc.get_blog(limit=20)[-1] cls.authorperm = comment.authorperm votes = acc.get_account_votes() last_vote = votes[-1] cls.authorpermvoter = '@' + last_vote['authorperm'] + '|' + acc["name"]
def test_history(): # TODO 1: test is disabled because d.creativechain.net account history # pruning is temporarily in place, breaking assumptions. # TODO 2: in addition, the current pruning implementation fails # to remove the very first operation, revealing a bug in # history_reverse() which causes it to be included once # on every page, causing an item count mismatch. return a = Account('barbara2') h1 = [x['index'] for x in list(a.history())] h2 = [x['index'] for x in list(a.history_reverse())] # pprint(list(zip(h1, h2[::-1]))) # various tests of equality should pass assert len(h1) == len(h2) assert set(h1) == set(h2) == set(range(a.virtual_op_count() + 1)) assert h1 == h2[::-1] == list(range(a.virtual_op_count() + 1))
def test_allow(self): bts = self.bts self.assertIn(bts.prefix, "STX") acc = Account("crea", crea_instance=bts) self.assertIn(acc.crea.prefix, "STX") tx = acc.allow( "STX55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", account="crea", weight=1, threshold=1, permission="active", ) self.assertEqual((tx["operations"][0][0]), "account_update") op = tx["operations"][0][1] self.assertIn("active", op) self.assertIn( ["STX55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", '1'], op["active"]["key_auths"]) self.assertEqual(op["active"]["weight_threshold"], 1)
def test_sign_message(self): def new_refresh(self): dict.__init__( self, { "identifier": "test", "name": "test", "id_item": "name", "memo_key": "STM6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" }) with mock.patch("crea.account.Account.refresh", new=new_refresh): account = Account("test") account[ "memo_key"] = "STM6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" p = Message("message foobar").sign(account=account) Message(p).verify(account=account)
def upload(self, image, account, image_name=None): """ Uploads an image :param image: path to the image or image in bytes representation which should be uploaded :type image: str, bytes :param str account: Account which is used to upload. A posting key must be provided. :param str image_name: optional .. code-block:: python from crea import Crea from crea.imageuploader import ImageUploader stm = Crea(keys=["5xxx"]) # private posting key iu = ImageUploader(crea_instance=stm) iu.upload("path/to/image.png", "account_name") # "private posting key belongs to account_name """ account = Account(account, crea_instance=self.crea) if "posting" not in account: account.refresh() if "posting" not in account: raise AssertionError("Could not access posting permission") for authority in account["posting"]["key_auths"]: posting_wif = self.crea.wallet.getPrivateKeyForPublicKey( authority[0]) if isinstance(image, string_types): image_data = open(image, 'rb').read() elif isinstance(image, io.BytesIO): image_data = image.read() else: image_data = image message = py23_bytes(self.challenge, "ascii") + image_data signature = sign_message(message, posting_wif) signature_in_hex = hexlify(signature).decode("ascii") files = {image_name or 'image': image_data} url = "%s/%s/%s" % (self.base_url, account["name"], signature_in_hex) r = requests.post(url, files=files) return r.json()
def test_TransactionConstructor(self): stm = self.bts opTransfer = Transfer( **{ "from": "crea", "to": "crea1", "amount": Amount("1 CREA", crea_instance=stm), "memo": "" }) tx1 = TransactionBuilder(use_condenser_api=True, crea_instance=stm) tx1.appendOps(opTransfer) tx = TransactionBuilder(tx1, crea_instance=stm) self.assertFalse(tx.is_empty()) self.assertTrue(len(tx.list_operations()) == 1) self.assertTrue(repr(tx) is not None) self.assertTrue(str(tx) is not None) account = Account("crea", crea_instance=stm) tx.appendSigner(account, "active") self.assertTrue(len(tx.wifs) > 0) tx.sign() self.assertTrue(len(tx["signatures"]) > 0)
def test_transfer_memo(self): bts = self.bts bts.nobroadcast = False bts.wallet.unlock("123") acc = Account("crea", crea_instance=bts) tx = acc.transfer("crea1", 1.33, "CBD", memo="#Foobar") self.assertEqual(tx["operations"][0][0], "transfer") op = tx["operations"][0][1] self.assertIn("memo", op) self.assertIn("#", op["memo"]) m = Memo(from_account=op["from"], to_account=op["to"], crea_instance=bts) memo = m.decrypt(op["memo"]) self.assertEqual(memo, "Foobar") self.assertEqual(op["from"], "crea") self.assertEqual(op["to"], "crea1") amount = Amount(op["amount"], crea_instance=bts) self.assertEqual(float(amount), 1.33) bts.nobroadcast = True
def lookup_accounts(acclist): def user_info(accounts): if len(acclist) != len(accounts): print("OOPS:", len(acclist), len(accounts), acclist) for index in range(0, len(accounts)): a = accounts[index] account = acclist[index] vp = (a["vesting_shares"].amount + a["received_vesting_shares"].amount - a["delegated_vesting_shares"].amount) / 1000000.0 fish = "redfish" if vp >= 1.0: fish = "minnow" if vp >= 10.0: fish = "dolphin" if vp >= 100: fish = "orca" if vp > 1000: fish = "whale" racc = None proxy = None related = list() if a["recovery_account"] != "crea" and a[ "recovery_account"] != "": related.append(a["recovery_account"]) if a["proxy"] != "": related.append(a["proxy"]) self.wtw.set_account_info(account, fish, related) accl2 = list() if racc is not None and racc not in self.looked_up: accl2.append(racc) if proxy is not None and proxy not in self.looked_up: accl2.append(proxy) if len(accl2) > 0: lookup_accounts(accl2) accounts = [] for a in acclist: accounts.append(Account(a)) user_info(accounts)