def tx_multi_sig_create(ctx, src, master, threshold, fee, ots_key_index): """ Creates Multi Sig Create Transaction, that results into the formation of new multi_sig_address if accepted. """ signatories = [] weights = [] while True: address = click.prompt('Address of Signatory ', default='') if address == '': break weight = int(click.prompt('Weight ')) signatories.append(parse_qaddress(address)) weights.append(weight) try: _, src_xmss = _select_wallet(ctx, src) if not src_xmss: click.echo("A local wallet is required to sign the transaction") quit(1) address_src_pk = src_xmss.pk ots_key_index = validate_ots_index(ots_key_index, src_xmss) src_xmss.set_ots_index(ots_key_index) master_addr = None if master: master_addr = parse_qaddress(master) # FIXME: This could be problematic. Check fee_shor = _quanta_to_shor(fee) except KeyboardInterrupt: click.echo("Terminated by user") quit(1) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: stub = ctx.obj.get_stub_public_api() tx = MultiSigCreate.create(signatories=signatories, weights=weights, threshold=threshold, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) tx.sign(src_xmss) push_transaction_req = xrd_pb2.PushTransactionReq(transaction_signed=tx.pbdata) push_transaction_resp = stub.PushTransaction(push_transaction_req, timeout=CONNECTION_TIMEOUT) print(push_transaction_resp.error_code) print('Multi sig Address Q{}'.format(bin2hstr(MultiSigAddressState.generate_multi_sig_address(tx.txhash)))) except Exception as e: print("Error {}".format(str(e)))
def token_list(ctx, owner): """ Fetch the list of tokens owned by an address. """ try: owner_address = parse_qaddress(owner) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: stub = ctx.obj.get_stub_public_api() address_state_req = xrd_pb2.GetAddressStateReq(address=owner_address) address_state_resp = stub.GetAddressState(address_state_req, timeout=CONNECTION_TIMEOUT) for token_hash in address_state_resp.state.tokens: get_object_req = xrd_pb2.GetObjectReq(query=bytes(hstr2bin(token_hash))) get_object_resp = stub.GetObject(get_object_req, timeout=CONNECTION_TIMEOUT) click.echo('Hash: %s' % (token_hash,)) click.echo('Symbol: %s' % (get_object_resp.transaction.tx.token.symbol.decode(),)) click.echo('Name: %s' % (get_object_resp.transaction.tx.token.name.decode(),)) click.echo('Balance: %s' % (address_state_resp.state.tokens[token_hash],)) except Exception as e: print("Error {}".format(str(e)))
def _select_wallet(ctx, address_or_index): try: wallet = Wallet(wallet_path=ctx.obj.wallet_path) if not wallet.addresses: click.echo('This command requires a local wallet') return if wallet.encrypted: secret = click.prompt('The wallet is encrypted. Enter password', hide_input=True) wallet.decrypt(secret) if address_or_index.isdigit(): address_or_index = int(address_or_index) addr_item = get_item_from_wallet(wallet, address_or_index) if addr_item: # FIXME: This should only return pk and index xmss = wallet.get_xmss_by_index(address_or_index) return wallet.addresses[address_or_index], xmss elif address_or_index.startswith('Q'): for i, addr_item in enumerate(wallet.address_items): if address_or_index == addr_item.qaddress: xmss = wallet.get_xmss_by_address(wallet.addresses[i]) return wallet.addresses[i], xmss click.echo('Source address not found in your wallet', color='yellow') quit(1) return parse_qaddress(address_or_index), None except Exception as e: click.echo("Error selecting wallet") click.echo(str(e)) quit(1)
def slave_tx_generate(ctx, src, master, number_of_slaves, access_type, fee, pk, ots_key_index): """ Generates Slave Transaction for the wallet """ try: _, src_xmss = _select_wallet(ctx, src) ots_key_index = validate_ots_index(ots_key_index, src_xmss) src_xmss.set_ots_index(ots_key_index) if src_xmss: address_src_pk = src_xmss.pk else: address_src_pk = pk.encode() master_addr = None if master: master_addr = parse_qaddress(master) fee_shor = _quanta_to_shor(fee) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) slave_xmss = [] slave_pks = [] access_types = [] slave_xmss_seed = [] if number_of_slaves > 100: click.echo("Error: Max Limit for the number of slaves is 100") quit(1) for i in range(number_of_slaves): print("Generating Slave #" + str(i + 1)) xmss = XMSS.from_height(config.dev.xmss_tree_height) slave_xmss.append(xmss) slave_xmss_seed.append(xmss.extended_seed) slave_pks.append(xmss.pk) access_types.append(access_type) print("Successfully Generated Slave %s/%s" % (str(i + 1), number_of_slaves)) try: tx = SlaveTransaction.create(slave_pks=slave_pks, access_types=access_types, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) tx.sign(src_xmss) with open('slaves.json', 'w') as f: json.dump([bin2hstr(src_xmss.address), slave_xmss_seed, tx.to_json()], f) click.echo('Successfully created slaves.json') click.echo('Move slaves.json file from current directory to the mining node inside ~/.xrd/') except Exception as e: click.echo("Unhandled error: {}".format(str(e))) quit(1)
def tx_message(ctx, src, master, addr_to, message, fee, ots_key_index): """ Message Transaction """ try: _, src_xmss = _select_wallet(ctx, src) if not src_xmss: click.echo("A local wallet is required to sign the transaction") quit(1) address_src_pk = src_xmss.pk ots_key_index = validate_ots_index(ots_key_index, src_xmss) src_xmss.set_ots_index(ots_key_index) message = message.encode() addr_to = parse_qaddress(addr_to, False) master_addr = None if master: master_addr = parse_qaddress(master) fee_shor = _quanta_to_shor(fee) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: stub = ctx.obj.get_stub_public_api() tx = MessageTransaction.create(message_hash=message, addr_to=addr_to, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) tx.sign(src_xmss) push_transaction_req = xrd_pb2.PushTransactionReq(transaction_signed=tx.pbdata) push_transaction_resp = stub.PushTransaction(push_transaction_req, timeout=CONNECTION_TIMEOUT) print(push_transaction_resp) except Exception as e: print("Error {}".format(str(e)))
def tx_transfertoken(ctx, src, master, token_txhash, dsts, amounts, decimals, fee, ots_key_index): """ Create Transfer Token Transaction, which moves tokens from src to dst. """ if decimals > 19: click.echo("The number of decimal cannot exceed 19 under any configuration") quit(1) try: addresses_dst, shor_amounts = _parse_dsts_amounts(dsts, amounts, token_decimals=decimals) bin_token_txhash = parse_hexblob(token_txhash) master_addr = None if master: master_addr = parse_qaddress(master) # FIXME: This could be problematic. Check fee_shor = _quanta_to_shor(fee) _, src_xmss = _select_wallet(ctx, src) if not src_xmss: click.echo("A local wallet is required to sign the transaction") quit(1) address_src_pk = src_xmss.pk ots_key_index = validate_ots_index(ots_key_index, src_xmss) src_xmss.set_ots_index(ots_key_index) except KeyboardInterrupt: click.echo("Terminated by user") quit(1) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: stub = ctx.obj.get_stub_public_api() tx = TransferTokenTransaction.create(token_txhash=bin_token_txhash, addrs_to=addresses_dst, amounts=shor_amounts, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) tx.sign(src_xmss) push_transaction_req = xrd_pb2.PushTransactionReq(transaction_signed=tx.pbdata) push_transaction_resp = stub.PushTransaction(push_transaction_req, timeout=CONNECTION_TIMEOUT) print(push_transaction_resp.error_code) except Exception as e: print("Error {}".format(str(e)))
def _parse_dsts_amounts(addresses: str, amounts: str, token_decimals: int = 0, check_multi_sig_address=False): """ 'Qaddr1 Qaddr2...' -> [\\xcx3\\xc2, \\xc2d\\xc3] '10 10' -> [10e9, 10e9] (in shor) :param addresses: :param amounts: :return: """ addresses_split = [parse_qaddress(addr, check_multi_sig_address) for addr in addresses.split(' ')] if token_decimals != 0: multiplier = Decimal(10 ** int(token_decimals)) shor_amounts = [_quanta_to_shor(Decimal(amount), base=multiplier) for amount in amounts.split(' ')] else: shor_amounts = [_quanta_to_shor(Decimal(amount)) for amount in amounts.split(' ')] if len(addresses_split) != len(shor_amounts): raise Exception("dsts and amounts should be the same length") return addresses_split, shor_amounts
def setUp(self): self.time = 1526830525 self.m_mining_qaddress = alice.qaddress self.m_mining_address = parse_qaddress(self.m_mining_qaddress) self.chain_manager = Mock(spec=ChainManager) self.chain_manager.get_block_size_limit.return_value = 500 self.chain_manager.get_config_by_block_number.return_value = config.dev self.parent_block = Block() self.parent_difficulty = StringToUInt256('0') # tuple (0,0,0,0,0...) length 32 self.m_pre_block_logic = Mock(spec=POW.pre_block_logic, name='hello') mining_thread_count = 1 self.miner = Miner(self.chain_manager, self.m_pre_block_logic, self.m_mining_address, mining_thread_count) self.txpool = Mock(spec=TransactionPool) self.txpool.transactions = []
def setUp(self): self.m_mining_qaddress = alice.qaddress self.m_mining_address = parse_qaddress(self.m_mining_qaddress) self.alice_address_state = Mock(autospec=OptimizedAddressState, name='mock alice OptimizedAddressState') self.chain_manager = Mock(spec=ChainManager) self.chain_manager.get_block_size_limit.return_value = 500 self.chain_manager.get_address_state.return_value = self.alice_address_state self.chain_manager.get_config_by_block_number.return_value = config.dev self.parent_block = Block() self.parent_difficulty = StringToUInt256('0') # tuple (0,0,0,0,0...) length 32 self.m_pre_block_logic = Mock(spec=POW.pre_block_logic, name='hello') mining_thread_count = 1 self.miner = Miner(self.chain_manager, self.m_pre_block_logic, self.m_mining_address, mining_thread_count) self.txpool = TransactionPool(None) def replacement_set_affected_address(addresses_set): return addresses_set.add(alice.address) self.m_tx_args = {"addr_from": alice.address, "addrs_to": [bob.address], "amounts": [10], "fee": 1, "PK": alice.pk, "master_addr": None, "size": 150, "validate_extended.return_value": True, "set_affected_address": replacement_set_affected_address }
def tx_token(ctx, src, master, symbol, name, owner, decimals, fee, ots_key_index): """ Create Token Transaction, that results into the formation of new token if accepted. """ initial_balances = [] if decimals > 19: click.echo("The number of decimal cannot exceed 19 under any possible configuration") quit(1) while True: address = click.prompt('Address ', default='') if address == '': break amount = int(click.prompt('Amount ')) * (10 ** int(decimals)) initial_balances.append(xrd_pb2.AddressAmount(address=parse_qaddress(address), amount=amount)) try: _, src_xmss = _select_wallet(ctx, src) if not src_xmss: click.echo("A local wallet is required to sign the transaction") quit(1) address_src_pk = src_xmss.pk ots_key_index = validate_ots_index(ots_key_index, src_xmss) src_xmss.set_ots_index(ots_key_index) address_owner = parse_qaddress(owner) master_addr = None if master: master_addr = parse_qaddress(master) # FIXME: This could be problematic. Check fee_shor = _quanta_to_shor(fee) if len(name) > config.dev.max_token_name_length: raise Exception("Token name must be shorter than {} chars".format(config.dev.max_token_name_length)) if len(symbol) > config.dev.max_token_symbol_length: raise Exception("Token symbol must be shorter than {} chars".format(config.dev.max_token_symbol_length)) except KeyboardInterrupt: click.echo("Terminated by user") quit(1) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: stub = ctx.obj.get_stub_public_api() tx = TokenTransaction.create(symbol=symbol.encode(), name=name.encode(), owner=address_owner, decimals=decimals, initial_balances=initial_balances, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) tx.sign(src_xmss) push_transaction_req = xrd_pb2.PushTransactionReq(transaction_signed=tx.pbdata) push_transaction_resp = stub.PushTransaction(push_transaction_req, timeout=CONNECTION_TIMEOUT) print(push_transaction_resp.error_code) except Exception as e: print("Error {}".format(str(e)))
def tx_transfer(ctx, src, master, dsts, amounts, message_data, fee, ots_key_index): """ Transfer coins from src to dsts """ address_src_pk = None master_addr = None addresses_dst = [] shor_amounts = [] fee_shor = [] signing_object = None message_data = message_data.encode() try: # Retrieve signing object selected_wallet = _select_wallet(ctx, src) if selected_wallet is None or len(selected_wallet) != 2: click.echo("A wallet was not found") quit(1) _, src_xmss = selected_wallet if not src_xmss: click.echo("A local wallet is required to sign the transaction") quit(1) address_src_pk = src_xmss.pk ots_key_index = validate_ots_index(ots_key_index, src_xmss) src_xmss.set_ots_index(ots_key_index) signing_object = src_xmss # Get and validate other inputs if master: master_addr = parse_qaddress(master) addresses_dst, shor_amounts = _parse_dsts_amounts(dsts, amounts, check_multi_sig_address=True) fee_shor = _quanta_to_shor(fee) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: # Create transaction tx = TransferTransaction.create(addrs_to=addresses_dst, amounts=shor_amounts, message_data=message_data, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) # Sign transaction tx.sign(signing_object) # Print result txjson = tx_unbase64(tx.to_json()) print(txjson) if not tx.validate(): print("It was not possible to validate the signature") quit(1) print("\nTransaction Blob (signed): \n") txblob = tx.pbdata.SerializeToString() txblobhex = hexlify(txblob).decode() print(txblobhex) # Push transaction print("Sending to a xrd Node...") stub = ctx.obj.get_stub_public_api() push_transaction_req = xrd_pb2.PushTransactionReq(transaction_signed=tx.pbdata) push_transaction_resp = stub.PushTransaction(push_transaction_req, timeout=CONNECTION_TIMEOUT) # Print result print(push_transaction_resp) except Exception as e: print("Error {}".format(str(e)))
def _public_get_address_balance(ctx, address): stub = ctx.obj.get_stub_public_api() get_address_state_req = xrd_pb2.GetAddressStateReq(address=parse_qaddress(address)) get_optimized_address_state_resp = stub.GetOptimizedAddressState(get_address_state_req, timeout=CONNECTION_TIMEOUT) return get_optimized_address_state_resp.state.balance