async def test_finalizeOps_proposal2(bitshares): bitshares.clear() proposal = bitshares.new_proposal() await bitshares.transfer("init1", 2, "TEST", append_to=proposal) tx = await bitshares.tx().json() # default tx buffer ops = tx["operations"] assert len(ops) == 1 assert getOperationNameForId(ops[0][0]) == "proposal_create" prop = ops[0][1] assert len(prop["proposed_ops"]) == 1 assert getOperationNameForId( prop["proposed_ops"][0]["op"][0]) == "transfer"
def test_finalizeOps_changeproposer_new(self): proposal = bitshares.proposal(proposer="init5") bitshares.transfer("init1", 1, "X4T", append_to=proposal) tx = bitshares.tx().json() ops = tx["operations"] self.assertEqual(len(ops), 1) self.assertEqual(getOperationNameForId(ops[0][0]), "proposal_create") prop = ops[0][1] self.assertEqual(len(prop["proposed_ops"]), 1) self.assertEqual(prop["fee_paying_account"], "1.2.90747") self.assertEqual( getOperationNameForId(prop["proposed_ops"][0]["op"][0]), "transfer")
def test_finalizeOps_proposal2(self): proposal = bitshares.new_proposal() # proposal = bitshares.proposal() bitshares.transfer("init1", 1, "X4T", append_to=proposal) tx = bitshares.tx().json() # default tx buffer ops = tx["operations"] self.assertEqual(len(ops), 1) self.assertEqual(getOperationNameForId(ops[0][0]), "proposal_create") prop = ops[0][1] self.assertEqual(len(prop["proposed_ops"]), 1) self.assertEqual( getOperationNameForId(prop["proposed_ops"][0]["op"][0]), "transfer")
async def test_finalizeOps_changeproposer_new(bitshares): bitshares.clear() proposal = bitshares.proposal(proposer="init5") await bitshares.transfer("init1", 5, "TEST", append_to=proposal) tx = await bitshares.tx().json() ops = tx["operations"] assert len(ops) == 1 assert getOperationNameForId(ops[0][0]) == "proposal_create" prop = ops[0][1] assert len(prop["proposed_ops"]) == 1 assert prop["fee_paying_account"] == "1.2.11" assert getOperationNameForId( prop["proposed_ops"][0]["op"][0]) == "transfer"
async def test_finalizeOps_combined_proposal(bitshares): bitshares.clear() parent = bitshares.new_tx() proposal = bitshares.new_proposal(parent) await bitshares.transfer("init1", 3, "TEST", append_to=proposal) await bitshares.transfer("init1", 4, "TEST", append_to=parent) tx = await parent.json() ops = tx["operations"] assert len(ops) == 2 assert getOperationNameForId(ops[0][0]) == "proposal_create" assert getOperationNameForId(ops[1][0]) == "transfer" prop = ops[0][1] assert len(prop["proposed_ops"]) == 1 assert getOperationNameForId( prop["proposed_ops"][0]["op"][0]) == "transfer"
def test_finalizeOps_combined_proposal(self): parent = bitshares.new_tx() proposal = bitshares.new_proposal(parent) bitshares.transfer("init1", 1, "X4T", append_to=proposal) bitshares.transfer("init1", 1, "X4T", append_to=parent) tx = parent.json() ops = tx["operations"] self.assertEqual(len(ops), 2) self.assertEqual(getOperationNameForId(ops[0][0]), "proposal_create") self.assertEqual(getOperationNameForId(ops[1][0]), "transfer") prop = ops[0][1] self.assertEqual(len(prop["proposed_ops"]), 1) self.assertEqual( getOperationNameForId(prop["proposed_ops"][0]["op"][0]), "transfer")
def test_finalizeOps_changeproposer_legacy(self): bts = self.bts bts.proposer = "init5" tx = bts.transfer("init1", 1, "TEST") ops = tx["operations"] self.assertEqual(len(ops), 1) self.assertEqual( getOperationNameForId(ops[0][0]), "proposal_create") prop = ops[0][1] self.assertEqual(len(prop["proposed_ops"]), 1) self.assertEqual(prop["fee_paying_account"], "1.2.11") self.assertEqual( getOperationNameForId(prop["proposed_ops"][0]["op"][0]), "transfer")
def test_approvecommittee(self): bts = self.bts tx = bts.approvecommittee("init0") self.assertEqual(getOperationNameForId(tx["operations"][0][0]), "account_update") op = tx["operations"][0][1] self.assertIn("0:11", op["new_options"]["votes"])
def ops(self, start=None, stop=None, **kwargs): """ Yields all operations (including virtual operations) starting from ``start``. :param int start: Starting block :param int stop: Stop at this block :param str mode: We here have the choice between "head" (the last block) and "irreversible" (the block that is confirmed by 2/3 of all block producers and is thus irreversible) :param bool only_virtual_ops: Only yield virtual operations This call returns a list that only carries one operation and its type! """ for block in self.blocks(start=start, stop=stop, **kwargs): for tx in block["transactions"]: for op in tx["operations"]: # Replace opid by op name op[0] = getOperationNameForId(op[0]) yield { "block_num": block["block_num"], "op": op, "timestamp": block["timestamp"] }
def fees(ctx, currency): """ List fees """ from bitsharesbase.operationids import getOperationNameForId from bitshares.market import Market market = Market("%s:%s" % (currency, "BTS")) ticker = market.ticker() if "quoteSettlement_price" in ticker: price = ticker.get("quoteSettlement_price") else: price = ticker.get("latest", 0) price.invert() chain = Blockchain(bitshares_instance=ctx.bitshares) feesObj = chain.chainParameters().get("current_fees") fees = feesObj["parameters"] t = [["Operation", "Type", "Fee", currency]] for fee in fees: for f in fee[1]: data = [ highlight(getOperationNameForId(fee[0])), detail(f), detail(Amount({"amount": fee[1].get(f, 0), "asset_id": "1.3.0"})), detail( price * Amount({"amount": fee[1].get(f, 0), "asset_id": "1.3.0"}) ), ] t.append(data) print_table(t)
def test_approvewitness(self): bts = self.bts tx = bts.approvewitness("1.6.1") self.assertEqual(getOperationNameForId(tx["operations"][0][0]), "account_update") op = tx["operations"][0][1] self.assertIn("1:0", op["new_options"]["votes"])
def test_create_account(self): bts = self.bts name = ''.join(random.choice(string.ascii_lowercase) for _ in range(12)) key1 = PrivateKey() key2 = PrivateKey() key3 = PrivateKey() key4 = PrivateKey() tx = bts.create_account( name, registrar="init0", # 1.2.7 referrer="init1", # 1.2.8 referrer_percent=33, owner_key=format(key1.pubkey, core_unit), active_key=format(key2.pubkey, core_unit), memo_key=format(key3.pubkey, core_unit), additional_owner_keys=[format(key4.pubkey, core_unit)], additional_active_keys=[format(key4.pubkey, core_unit)], additional_owner_accounts=["committee-account"], # 1.2.0 additional_active_accounts=["committee-account"], proxy_account="init0", storekeys=False ) self.assertEqual( getOperationNameForId(tx["operations"][0][0]), "account_create" ) op = tx["operations"][0][1] role = "active" self.assertIn( format(key4.pubkey, core_unit), [x[0] for x in op[role]["key_auths"]]) self.assertIn( format(key4.pubkey, core_unit), [x[0] for x in op[role]["key_auths"]]) self.assertIn( "1.2.0", [x[0] for x in op[role]["account_auths"]]) role = "owner" self.assertIn( format(key4.pubkey, core_unit), [x[0] for x in op[role]["key_auths"]]) self.assertIn( format(key4.pubkey, core_unit), [x[0] for x in op[role]["key_auths"]]) self.assertIn( "1.2.0", [x[0] for x in op[role]["account_auths"]]) self.assertEqual( op["options"]["voting_account"], "1.2.6") self.assertEqual( op["registrar"], "1.2.6") self.assertEqual( op["referrer"], "1.2.7") self.assertEqual( op["referrer_percent"], 33 * 100)
def test_update_memo_key(self): tx = bitshares.update_memo_key( "BTS55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n") self.assertEqual(getOperationNameForId(tx["operations"][0][0]), "account_update") op = tx["operations"][0][1] self.assertEqual( op["new_options"]["memo_key"], "BTS55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n")
def test_account_upgrade(self): account = Account("init0") pprint(account) tx = account.upgrade() ops = tx["operations"] op = ops[0][1] self.assertEqual(len(ops), 1) self.assertEqual(getOperationNameForId(ops[0][0]), "account_upgrade") self.assertTrue(op["upgrade_to_lifetime_member"]) self.assertEqual(op["account_to_upgrade"], "1.2.100")
def test_transfer(self): tx = bitshares.transfer( "1.2.101", 1.33, "X4T", memo="Foobar", account="init0") self.assertEqual( getOperationNameForId(tx["operations"][0][0]), "transfer" ) op = tx["operations"][0][1] self.assertIn("memo", op) self.assertEqual(op["from"], "1.2.100") self.assertEqual(op["to"], "1.2.101") amount = Amount(op["amount"]) self.assertEqual(float(amount), 1.33)
def test_allow(self): tx = bitshares.allow( "BTS55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", weight=1, threshold=1, permission="owner") self.assertEqual(getOperationNameForId(tx["operations"][0][0]), "account_update") op = tx["operations"][0][1] self.assertIn("owner", op) self.assertIn( ["BTS55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", '1'], op["owner"]["key_auths"]) self.assertEqual(op["owner"]["weight_threshold"], 1)
def fees_parser(self, start_date, end_date, csv_file="Untitled"): """ This parses the BitShares blockchain and aggregates historical fee data by type. The user is expected to input start and end dates on the user interface, which will be passed into this method. The dates need to be in datetime format.""" # This will pass in the start date and retrieve the block number for the first block to parse begin = self.block_search(start_date) # This will pass in the end date and retrieve the block number for # the last block to parse. As we want to fully capture the transactions # of the last day, we will pass in the next day's date and stop at the block just prior. stop = self.block_search(end_date + timedelta(days=1)) - 1 # List to temporarily hold the dictionaries until we store them in a dataframe storage = [] # We will iterate through the blocks and store relevant block information in a dictionary for blocknum in range(begin, stop + 1): # Dictionary to store block information block_data = dict() # To retrieve the blocks from the blockchain block = shared_bitshares_instance().rpc.get_block(blocknum) # Record the dates ts = pd.Timestamp(block["timestamp"]) block_data["Date"] = datetime.date(ts) # Iterating through the data within each block for tx in block["transactions"]: for op in tx["operations"]: key = getOperationNameForId(op[0]) # If the fee was paid in BTS, add the fee amount to the running total for each operation type if op[1]["fee"].get("asset_id") == "1.3.0": block_data[key] = block_data.get( key, 0) + op[1]["fee"].get("amount") # Append the dictionaries to the list for each block so that the data won't be lost storage.append(block_data) # Creating a dataframe to store the fee information data = pd.DataFrame(storage) data.fillna(0, inplace=True) # Aggregating at the daily level daily = data.groupby("Date") daily = daily.sum() daily.to_csv(str(csv_file) + ".csv")
def test_transfer(self): bts = self.bts tx = bts.transfer( "1.2.8", 1.33, core_unit, memo="Foobar", account="1.2.7") self.assertEqual( getOperationNameForId(tx["operations"][0][0]), "transfer" ) op = tx["operations"][0][1] self.assertIn("memo", op) self.assertEqual(op["from"], "1.2.7") self.assertEqual(op["to"], "1.2.8") amount = Amount(op["amount"]) self.assertEqual(float(amount), 1.33)
def process_transaction(self, transaction): """ Process transaction and send operations to :func:`BlockchainMonitor.process_operation` :param dict transaction: Individual transaction as dictionary This method takes a transaction (appends transaction-specific informations) and sends all operations in it to operation processing """ def get_tx_id(transaction): """ This method is used as a *getter* that is handed over as lambda function so we don't need to derive transaction ids for every transaction but instead only obtain the transaction id on those transactions that contain operations that we are interested in. """ if self.bitshares.prefix != "BTS": transaction["operations"][0][1].update({"prefix": self.bitshares.prefix}) tx = Signed_Transaction(**transaction) return tx.id for op_in_tx, operation in enumerate(transaction.get("operations", [])): # op_in_tx tells us which operation in the transaction we are # talking about. Technically, multiple deposits could be made in a # single transaction. This is why we need to ensure we can # distinguish them. self.process_operation( { "block_num": transaction.get("block_num"), "timestamp": transaction.get("timestamp"), "expiration": transaction.get("expiration"), "tx_in_block": transaction.get("tx_in_block"), "op_in_tx": op_in_tx, "op": [ # Decode the operation type id as string getOperationNameForId(operation[0]), # Operation payload operation[1] ], }, # This is a getter lambda that allows us to obtain a # transaction id for a transaction but allows us to only derive # it for those transactions that contain operations of # interest. tx_id_getter=(lambda: get_tx_id(transaction)) )
def fees(ctx, currency): """ List fees """ from bitsharesbase.operationids import getOperationNameForId from bitshares.market import Market market = Market("%s:%s" % (currency, "BTS")) ticker = market.ticker() if "quoteSettlement_price" in ticker: price = ticker.get("quoteSettlement_price") else: price = ticker.get("latest", 0) chain = Blockchain(bitshares_instance=ctx.bitshares) feesObj = chain.chainParameters().get("current_fees") scale = feesObj["scale"] fees = feesObj["parameters"] t = PrettyTable(["Operation", "Type", "Fee", currency]) t.align = "l" t.align["Fee"] = "r" t.align[currency] = "r" for fee in fees: for f in fee[1]: t.add_row([ getOperationNameForId(fee[0]), f, str(Amount({ "amount": fee[1].get(f, 0), "asset_id": "1.3.0" })), str(price * Amount({ "amount": fee[1].get(f, 0), "asset_id": "1.3.0" })) ]) click.echo(t)
def test_create_asset(self): symbol = "FOOBAR" precision = 7 max_supply = 100000 description = "Test asset" is_bitasset = True market_fee_percent = 0.1 max_market_fee = 10 blacklist_authorities = ["init1"] blacklist_authorities_ids = [ Account(a)["id"] for a in blacklist_authorities ] blacklist_markets = ["BTS"] blacklist_markets_ids = ["1.3.0"] permissions = { "charge_market_fee": True, "white_list": True, "override_authority": True, "transfer_restricted": True, "disable_force_settle": True, "global_settle": True, "disable_confidential": True, "witness_fed_asset": True, "committee_fed_asset": True, } flags = { "charge_market_fee": False, "white_list": False, "override_authority": False, "transfer_restricted": False, "disable_force_settle": False, "global_settle": False, "disable_confidential": False, "witness_fed_asset": False, "committee_fed_asset": False, } tx = bitshares.create_asset( symbol, precision, max_supply, market_fee_percent=market_fee_percent, max_market_fee=max_market_fee, description=description, is_bitasset=is_bitasset, blacklist_authorities=blacklist_authorities, blacklist_markets=blacklist_markets, permissions=permissions, flags=flags, ) self.assertEqual(getOperationNameForId(tx["operations"][0][0]), "asset_create") op = tx["operations"][0][1] self.assertEqual(op["issuer"], "1.2.100") self.assertEqual(op["symbol"], symbol) self.assertEqual(op["precision"], precision) self.assertEqual(op["common_options"]["max_supply"], int(max_supply * 10**precision)) self.assertEqual(op["common_options"]["market_fee_percent"], int(market_fee_percent * 100)) self.assertEqual( op["common_options"]["max_market_fee"], int(max_market_fee * 10**precision), ) self.assertEqual(op["common_options"]["description"], description) self.assertEqual(op["common_options"]["blacklist_authorities"], blacklist_authorities_ids) self.assertEqual(op["common_options"]["blacklist_markets"], blacklist_markets_ids) self.assertEqual(todict(op["common_options"]["issuer_permissions"]), permissions) self.assertEqual(todict(op["common_options"]["flags"]), flags)