def prepare_transfer_tx(hw_session: HwSessionInfo, utxos_to_spend: List[dict], dest_addresses: List[Tuple[str, int, str]], tx_fee): """ Creates a signed transaction. :param hw_session: :param utxos_to_spend: list of utxos to send :param dest_address: destination (Dash) address :param tx_fee: transaction fee :return: tuple (serialized tx, total transaction amount in satoshis) """ insight_network = 'insight_dash' if hw_session.app_config.is_testnet(): insight_network += '_testnet' dash_network = hw_session.app_config.dash_network tx_api = MyTxApiInsight(insight_network, '', hw_session.zyrkd_intf, hw_session.app_config.cache_dir) client = hw_session.hw_client client.set_tx_api(tx_api) inputs = [] outputs = [] inputs_amount = 0 for utxo_index, utxo in enumerate(utxos_to_spend): if not utxo.get('bip32_path', None): raise Exception('No BIP32 path for UTXO ' + utxo['txid']) address_n = client.expand_path(clean_bip32_path(utxo['bip32_path'])) it = proto_types.TxInputType(address_n=address_n, prev_hash=binascii.unhexlify(utxo['txid']), prev_index=utxo['outputIndex']) inputs.append(it) inputs_amount += utxo['satoshis'] outputs_amount = 0 for addr, amount, bip32_path in dest_addresses: outputs_amount += amount if addr[0] in dash_utils.get_chain_params(dash_network).B58_PREFIXES_SCRIPT_ADDRESS: stype = proto_types.PAYTOSCRIPTHASH logging.debug('Transaction type: PAYTOSCRIPTHASH' + str(stype)) elif addr[0] in dash_utils.get_chain_params(dash_network).B58_PREFIXES_PUBKEY_ADDRESS: stype = proto_types.PAYTOADDRESS logging.debug('Transaction type: PAYTOADDRESS ' + str(stype)) else: raise Exception('Invalid prefix of the destination address.') if bip32_path: address_n = client.expand_path(bip32_path) else: address_n = None ot = proto_types.TxOutputType( address=addr if address_n is None else None, address_n=address_n, amount=amount, script_type=stype ) outputs.append(ot) if outputs_amount + tx_fee != inputs_amount: raise Exception('Transaction validation failure: inputs + fee != outputs') signed = client.sign_tx(hw_session.app_config.hw_coin_name, inputs, outputs) logging.info('Signed transaction') return signed[1], inputs_amount
def __init__(self, parent, app_config: AppConfig, all_mns: bool): columns = [ TableModelColumn("ip_address", "IP Address", True, 100), TableModelColumn("protocol", "Protocol", True, 60), TableModelColumn("status", "Status", True, 100), TableModelColumn("activeseconds", "Active Time", True, 80), TableModelColumn("lastseen", "Last Seen", True, 80), TableModelColumn("payee_address", "Collateral Address", True, 120) ] if not all_mns: columns.insert(0, TableModelColumn("alias", "Name", True, 80)) ExtSortFilterTableModel.__init__(self, parent, columns, True, True) wnd_utils.WndUtils.__init__(self, None) self.port = str( dash_utils.get_chain_params(app_config.dash_network).P2P_PORT) self.all = all_mns self.dashd_intf = parent.dashd_intf self.mnlist = app_config.masternodes self.parent = parent self.set_attr_protection()
def sign_tx(hw_session: HWSessionBase, rt_data: AppRuntimeData, utxos_to_spend: List[wallet_common.UtxoType], tx_outputs: List[wallet_common.TxOutputType], tx_fee): """ Creates a signed transaction. :param hw_session: :param utxos_to_spend: list of utxos to send :param tx_outputs: list of transaction outputs :param tx_fee: transaction fee :return: tuple (serialized tx, total transaction amount in satoshis) """ def load_prev_txes(tx_api_, skip_cache_: bool = False): txes_ = {} tx_api_.skip_cache = skip_cache_ for utxo_ in utxos_to_spend: prev_hash_bin = bytes.fromhex(utxo_.txid) if prev_hash_bin not in txes_: tx = tx_api_.get_tx(utxo_.txid) txes_[prev_hash_bin] = tx return txes_ insight_network = 'insight_dash' if rt_data.is_testnet: insight_network += '_testnet' dash_network = rt_data.dash_network tx_api = MyTxApiInsight(rt_data.dashd_intf, rt_data.tx_cache_dir) client = hw_session.hw_client inputs = [] outputs = [] inputs_amount = 0 for utxo_index, utxo in enumerate(utxos_to_spend): if not utxo.bip32_path: raise Exception('No BIP32 path for UTXO ' + utxo.txid) address_n = dash_utils.bip32_path_string_to_n(utxo.bip32_path) it = trezor_proto.TxInputType(address_n=address_n, amount=utxo.satoshis, prev_hash=binascii.unhexlify(utxo.txid), prev_index=int(utxo.output_index)) inputs.append(it) inputs_amount += utxo.satoshis outputs_amount = 0 for out in tx_outputs: outputs_amount += out.satoshis if out.address[0] in dash_utils.get_chain_params( dash_network).B58_PREFIXES_SCRIPT_ADDRESS: stype = trezor_proto.OutputScriptType.PAYTOSCRIPTHASH logging.debug('Transaction type: PAYTOSCRIPTHASH' + str(stype)) elif out.address[0] in dash_utils.get_chain_params( dash_network).B58_PREFIXES_PUBKEY_ADDRESS: stype = trezor_proto.OutputScriptType.PAYTOADDRESS logging.debug('Transaction type: PAYTOADDRESS ' + str(stype)) else: raise Exception('Invalid prefix of the destination address.') if out.bip32_path: address_n = dash_utils.bip32_path_string_to_n(out.bip32_path) else: address_n = None ot = trezor_proto.TxOutputType( address=out.address if address_n is None else None, address_n=address_n, amount=out.satoshis, script_type=stype) outputs.append(ot) if outputs_amount + tx_fee != inputs_amount: raise Exception( 'Transaction validation failure: inputs + fee != outputs') try: for skip_cache in (False, True): txes = load_prev_txes(tx_api, skip_cache) try: signed = btc.sign_tx(client, rt_data.hw_coin_name, inputs, outputs, prev_txes=txes) return signed[1], inputs_amount except exceptions.Cancelled: raise except Exception: if skip_cache: raise log.exception( 'Exception occurred while signing transaction. Turning off the transaction cache ' 'and retrying...') raise Exception('Internal error: transaction not signed') except exceptions.Cancelled: raise CancelException('Cancelled') except exceptions.TrezorFailure as e: if e.failure.message == 'Device not initialized': raise HwNotInitialized(e.failure.message) else: raise
def sign_tx(hw_session: HWSessionBase, rt_data: AppRuntimeData, utxos_to_spend: List[wallet_common.UtxoType], tx_outputs: List[wallet_common.TxOutputType], tx_fee): """ Creates a signed transaction. :param hw_session: :param utxos_to_spend: list of utxos to send :param tx_outputs: list of transaction outputs :param tx_fee: transaction fee :return: tuple (serialized tx, total transaction amount in satoshis) """ insight_network = 'insight_dash' if rt_data.is_testnet: insight_network += '_testnet' dash_network = rt_data.dash_network tx_api = MyTxApiInsight(insight_network, '', rt_data.dashd_intf, rt_data.tx_cache_dir) client = hw_session.hw_client client.set_tx_api(tx_api) inputs = [] outputs = [] inputs_amount = 0 for utxo_index, utxo in enumerate(utxos_to_spend): if not utxo.bip32_path: raise Exception('No BIP32 path for UTXO ' + utxo.txid) address_n = client.expand_path(clean_bip32_path(utxo.bip32_path)) it = proto_types.TxInputType(address_n=address_n, prev_hash=binascii.unhexlify(utxo.txid), prev_index=utxo.output_index) inputs.append(it) inputs_amount += utxo.satoshis outputs_amount = 0 for out in tx_outputs: outputs_amount += out.satoshis if out.address[0] in dash_utils.get_chain_params( dash_network).B58_PREFIXES_SCRIPT_ADDRESS: stype = proto_types.PAYTOSCRIPTHASH logging.debug('Transaction type: PAYTOSCRIPTHASH' + str(stype)) elif out.address[0] in dash_utils.get_chain_params( dash_network).B58_PREFIXES_PUBKEY_ADDRESS: stype = proto_types.PAYTOADDRESS logging.debug('Transaction type: PAYTOADDRESS ' + str(stype)) else: raise Exception('Invalid prefix of the destination address.') if out.bip32_path: address_n = client.expand_path(out.bip32_path) else: address_n = None ot = proto_types.TxOutputType( address=out.address if address_n is None else None, address_n=address_n, amount=out.satoshis, script_type=stype) outputs.append(ot) if outputs_amount + tx_fee != inputs_amount: raise Exception( 'Transaction validation failure: inputs + fee != outputs') signed = client.sign_tx(rt_data.hw_coin_name, inputs, outputs) logging.info('Signed transaction') return signed[1], inputs_amount