def get_destination_view_key_pub(destinations, change_addr=None): """ Returns destination address public view key :param destinations: :type destinations: list[apps.monero.xmr.serialize_messages.tx_construct.TxDestinationEntry] :param change_addr: :return: """ from monero_glue.xmr.sub.addr import addr_eq addr = AccountPublicAddress( m_spend_public_key=crypto.NULL_KEY_ENC, m_view_public_key=crypto.NULL_KEY_ENC ) count = 0 for dest in destinations: if dest.amount == 0: continue if change_addr and addr_eq(dest.addr, change_addr): continue if addr_eq(dest.addr, addr): continue if count > 0: return crypto.NULL_KEY_ENC addr = dest.addr count += 1 return addr.m_view_public_key
def check_change(self, outputs): """ Checks if the change address is among tx outputs. :param outputs: :return: """ from monero_glue.xmr.sub.addr import addr_eq change_addr = self.change_address() if change_addr is None: return for out in outputs: if addr_eq(out.addr, change_addr): return True raise ValueError("Change address not found in outputs")
async def adjust_change(self, tx): logger.debug("Change addr adjust") out_txs2 = await self.reformat_outs(tx.splitted_dsts) change_dts = await self.reformat_out(tx.change_dts) if tx.change_dts else None change_idx = addr.get_change_addr_idx(out_txs2, change_dts) if change_idx is None: logger.warning('Change address not found in outputs, dts: %s' % (change_dts, )) for ii in out_txs2: logger.warning('Out: %s' % ii) # Find addr that matches and adapt value in change dst for idx, ii in enumerate(out_txs2): if addr.addr_eq(change_dts.addr, ii.addr): logger.info('Found surrogate change addr: [%s] %s' % (idx, ii)) change_dts.amount = ii.amount change_idx = idx break if self.args.outs_subs: for ix, o in enumerate(tx.splitted_dsts): if change_idx is None or ix != change_idx: o.is_subaddress = True if change_idx is None: logger.warning('Could not fix change addr') return change_addr = await self.primary_change_address( self.dest_keys, self.dest_sub_major ) tx.change_dts.amount = change_dts.amount tx.change_dts.addr.m_spend_public_key = change_addr.spend_public_key tx.change_dts.addr.m_view_public_key = change_addr.view_public_key logger.debug("Change addr adjust @idx: %s, spend key: %s" % (change_idx, binascii.hexlify(change_addr.spend_public_key))) tx.splitted_dsts[ change_idx ].addr.m_spend_public_key = change_addr.spend_public_key tx.splitted_dsts[ change_idx ].addr.m_view_public_key = change_addr.view_public_key return change_idx
def _get_integrated_idx(self, outputs, aux_data=None): if aux_data is None or aux_data.destinations is None: return [] integrated_indices = [] integrated_pairs = [] for idx, cur in enumerate(aux_data.destinations): ainfo = cur[0] if ainfo.is_integrated: caddr = xmr_addr.build_address(ainfo.spend_key, ainfo.view_key) integrated_pairs.append((caddr, cur[1])) for idx, dst in enumerate(outputs): for ipair in integrated_pairs: if xmr_addr.addr_eq(ipair[0], dst.addr) and dst.amount == ipair[1]: integrated_indices.append(idx) logger.debug("Integrated indices: %s" % len(integrated_indices)) return integrated_indices
async def _set_out1_derivation(self, dst_entr, additional_txkey_priv): from monero_glue.xmr.sub.addr import addr_eq change_addr = self.change_address() if change_addr and addr_eq(dst_entr.addr, change_addr): # sending change to yourself; derivation = a*R derivation = monero.generate_key_derivation( self.r_pub, self.creds.view_key_private ) else: # sending to the recipient; derivation = r*A (or s*C in the subaddress scheme) deriv_priv = ( additional_txkey_priv if dst_entr.is_subaddress and self.need_additional_txkeys else self.r ) derivation = monero.generate_key_derivation( crypto.decodepoint(dst_entr.addr.m_view_public_key), deriv_priv ) return derivation