Beispiel #1
0
    def tx_outputs(self, derivation, tx, segwit=False):
        outputs = []
        has_change = False

        for _type, address, amount in tx.outputs():
            info = tx.output_info.get(address)
            if info is not None and not has_change:
                has_change = True  # no more than one change address
                addrtype, hash_160 = b58_address_to_hash160(address)
                index, xpubs, m = info
                if len(xpubs) == 1:
                    script_type = self.types.PAYTOP2SHWITNESS if segwit else self.types.PAYTOADDRESS
                    address_n = self.client_class.expand_path(derivation +
                                                              "/%d/%d" % index)
                    txoutputtype = self.types.TxOutputType(
                        amount=amount,
                        script_type=script_type,
                        address_n=address_n,
                    )
                else:
                    script_type = self.types.PAYTOP2SHWITNESS if segwit else self.types.PAYTOMULTISIG
                    address_n = self.client_class.expand_path("/%d/%d" % index)
                    nodes = map(self.ckd_public.deserialize, xpubs)
                    pubkeys = [
                        self.types.HDNodePathType(node=node,
                                                  address_n=address_n)
                        for node in nodes
                    ]
                    multisig = self.types.MultisigRedeemScriptType(
                        pubkeys=pubkeys, signatures=[b''] * len(pubkeys), m=m)
                    txoutputtype = self.types.TxOutputType(
                        multisig=multisig,
                        amount=amount,
                        address_n=self.client_class.expand_path(derivation +
                                                                "/%d/%d" %
                                                                index),
                        script_type=script_type)
            else:
                txoutputtype = self.types.TxOutputType()
                txoutputtype.amount = amount
                if _type == TYPE_SCRIPT:
                    txoutputtype.script_type = self.types.PAYTOOPRETURN
                    txoutputtype.op_return_data = address[2:]
                elif _type == TYPE_ADDRESS:
                    if is_segwit_address(address):
                        txoutputtype.script_type = self.types.PAYTOWITNESS
                    else:
                        addrtype, hash_160 = b58_address_to_hash160(address)
                        if addrtype == NetworkConstants.ADDRTYPE_P2PKH:
                            txoutputtype.script_type = self.types.PAYTOADDRESS
                        elif addrtype == NetworkConstants.ADDRTYPE_P2SH:
                            txoutputtype.script_type = self.types.PAYTOSCRIPTHASH
                        else:
                            raise BaseException('addrtype: ' + str(addrtype))
                    txoutputtype.address = address

            outputs.append(txoutputtype)

        return outputs
Beispiel #2
0
    def tx_outputs(self, derivation, tx, segwit=False):
        outputs = []
        has_change = False

        for _type, address, amount in tx.outputs():
            info = tx.output_info.get(address)
            if info is not None and not has_change:
                has_change = True # no more than one change address
                addrtype, hash_160 = b58_address_to_hash160(address)
                index, xpubs, m = info
                if len(xpubs) == 1:
                    script_type = self.types.PAYTOP2SHWITNESS if segwit else self.types.PAYTOADDRESS
                    address_n = self.client_class.expand_path(derivation + "/%d/%d"%index)
                    txoutputtype = self.types.TxOutputType(
                        amount = amount,
                        script_type = script_type,
                        address_n = address_n,
                    )
                else:
                    script_type = self.types.PAYTOP2SHWITNESS if segwit else self.types.PAYTOMULTISIG
                    address_n = self.client_class.expand_path("/%d/%d"%index)
                    nodes = map(self.ckd_public.deserialize, xpubs)
                    pubkeys = [ self.types.HDNodePathType(node=node, address_n=address_n) for node in nodes]
                    multisig = self.types.MultisigRedeemScriptType(
                        pubkeys = pubkeys,
                        signatures = [b''] * len(pubkeys),
                        m = m)
                    txoutputtype = self.types.TxOutputType(
                        multisig = multisig,
                        amount = amount,
                        address_n = self.client_class.expand_path(derivation + "/%d/%d"%index),
                        script_type = script_type)
            else:
                txoutputtype = self.types.TxOutputType()
                txoutputtype.amount = amount
                if _type == TYPE_SCRIPT:
                    txoutputtype.script_type = self.types.PAYTOOPRETURN
                    txoutputtype.op_return_data = address[2:]
                elif _type == TYPE_ADDRESS:
                    if is_segwit_address(address):
                        txoutputtype.script_type = self.types.PAYTOWITNESS
                    else:
                        addrtype, hash_160 = b58_address_to_hash160(address)
                        if addrtype == constants.net.ADDRTYPE_P2PKH:
                            txoutputtype.script_type = self.types.PAYTOADDRESS
                        elif addrtype == constants.net.ADDRTYPE_P2SH:
                            txoutputtype.script_type = self.types.PAYTOSCRIPTHASH
                        else:
                            raise BaseException('addrtype: ' + str(addrtype))
                    txoutputtype.address = address

            outputs.append(txoutputtype)

        return outputs
Beispiel #3
0
    def test_is_valid_address(self):
        for priv_details in self.priv_pub_addr:
            addr = priv_details['address']
            self.assertFalse(is_address(priv_details['priv']))
            self.assertFalse(is_address(priv_details['pub']))
            self.assertTrue(is_address(addr))

            is_enc_b58 = priv_details['addr_encoding'] == 'base58'
            self.assertEqual(is_enc_b58, is_b58_address(addr))

            is_enc_bech32 = priv_details['addr_encoding'] == 'bech32'
            self.assertEqual(is_enc_bech32, is_segwit_address(addr))

        self.assertFalse(is_address("not an address"))
Beispiel #4
0
    def test_is_valid_address(self):
        for priv_details in self.priv_pub_addr:
            addr = priv_details['address']
            self.assertFalse(is_address(priv_details['priv']))
            self.assertFalse(is_address(priv_details['pub']))
            self.assertTrue(is_address(addr))

            is_enc_b58 = priv_details['addr_encoding'] == 'base58'
            self.assertEqual(is_enc_b58, is_b58_address(addr))

            is_enc_bech32 = priv_details['addr_encoding'] == 'bech32'
            self.assertEqual(is_enc_bech32, is_segwit_address(addr))

        self.assertFalse(is_address("not an address"))
Beispiel #5
0
 def create_output_by_address():
     txoutputtype = self.types.TxOutputType()
     txoutputtype.amount = amount
     if _type == TYPE_SCRIPT:
         txoutputtype.script_type = self.types.PAYTOOPRETURN
         txoutputtype.op_return_data = address[2:]
     elif _type == TYPE_ADDRESS:
         if is_segwit_address(address):
             txoutputtype.script_type = self.types.PAYTOWITNESS
         else:
             addrtype, hash_160 = b58_address_to_hash160(address)
             if addrtype == constants.net.ADDRTYPE_P2PKH:
                 txoutputtype.script_type = self.types.PAYTOADDRESS
             elif addrtype == constants.net.ADDRTYPE_P2SH:
                 txoutputtype.script_type = self.types.PAYTOSCRIPTHASH
             else:
                 raise Exception('addrtype: ' + str(addrtype))
         txoutputtype.address = address
     return txoutputtype
Beispiel #6
0
 def create_output_by_address():
     txoutputtype = self.types.TxOutputType()
     txoutputtype.amount = amount
     if _type == TYPE_SCRIPT:
         txoutputtype.script_type = self.types.PAYTOOPRETURN
         txoutputtype.op_return_data = trezor_validate_op_return_output_and_get_data(o)
     elif _type == TYPE_ADDRESS:
         if is_segwit_address(address):
             txoutputtype.script_type = self.types.PAYTOWITNESS
         else:
             addrtype, hash_160 = b58_address_to_hash160(address)
             if addrtype == constants.net.ADDRTYPE_P2PKH:
                 txoutputtype.script_type = self.types.PAYTOADDRESS
             elif addrtype == constants.net.ADDRTYPE_P2SH:
                 txoutputtype.script_type = self.types.PAYTOSCRIPTHASH
             else:
                 raise Exception('addrtype: ' + str(addrtype))
         txoutputtype.address = address
     return txoutputtype
Beispiel #7
0
def _ShowAddressContextMenu(entry,
                            parentvc,
                            ipadAnchor,
                            toggleFreezeCallback=None):
    parent = gui.ElectrumGui.gui
    if not parent.wallet:
        utils.NSLog(
            "_ShowAddressContextMenu: wallet is None -- possibly backgrounded/closed wallet. Returning early."
        )
        return

    def on_block_explorer() -> None:
        parent.view_on_block_explorer(entry.address, 'addr')

    def on_request_payment() -> None:
        parent.jump_to_receive_with_address(entry.address)

    def on_private_key() -> None:
        def onPw(password: str) -> None:
            # present the private key view controller here.
            pk = None
            try:
                pk = parent.wallet.export_private_key(
                    entry.address, password) if parent.wallet else None
            except:
                parent.show_error(str(sys.exc_info()[1]))
                return
            if pk:
                vc = private_key_dialog.PrivateKeyDialog.alloc().init(
                ).autorelease()
                pkentry = private_key_dialog.PrivateKeyEntry(
                    entry.address, pk, entry.is_frozen, entry.is_change)
                utils.nspy_put_byname(vc, pkentry, 'entry')
                parentvc.navigationController.pushViewController_animated_(
                    vc, True)

        parent.prompt_password_if_needed_asynch(onPw)

    def on_sign_verify() -> None:
        vc = sign_decrypt_dialog.Create_SignVerify_VC(entry.address)
        parentvc.navigationController.pushViewController_animated_(vc, True)

    def on_encrypt_decrypt() -> None:
        if not parent.wallet: return
        try:
            pubkey = parent.wallet.get_public_key(entry.address)
        except:
            print("exception extracting public key:", str(sys.exc_info()[1]))
            return
        if pubkey is not None and not isinstance(pubkey, str):
            pubkey = pubkey
        if not pubkey:
            return
        vc = sign_decrypt_dialog.Create_EncryptDecrypt_VC(
            entry.address, pubkey)
        parentvc.navigationController.pushViewController_animated_(vc, True)

    def on_copy() -> None:
        parent.copy_to_clipboard(entry.addr_str, 'Address')

    actions = [
        [_('Cancel')],
        [_('Copy Address'), on_copy],
        [_("Request payment"), on_request_payment],
    ]

    watch_only = entry.is_watch_only

    if entry.num_utxos and parentvc.navigationController:
        from .coins import PushCoinsVC
        actions.insert(2, [
            _('Show Coins (UTXOs)'), PushCoinsVC, [entry.address],
            parentvc.navigationController
        ])

    if isinstance(parentvc, AddressDetail):
        actions.insert(2,
                       [_('Share/Save QR...'), lambda: parentvc.onQRImgTap()])

    if not watch_only:

        def onToggleFreeze() -> None:
            _ToggleFreeze(entry)
            if callable(toggleFreezeCallback):
                toggleFreezeCallback()

        actions.append([
            _('Freeze') if not entry.is_frozen else _('Unfreeze'),
            onToggleFreeze
        ])

    if not watch_only and not entry.is_frozen and entry.balance > 0:
        actions.append([
            _('Spend from this Address'),
            lambda: _SpendFrom(entry, vc=parentvc)
        ])

    actions.append([_("View on block explorer"), on_block_explorer])

    if not watch_only:
        actions.append([_('Private key'), on_private_key])

    try:
        typ = b58_address_to_hash160(entry.address)[0]
        can_sign = typ == constants.net.ADDRTYPE_P2PKH
    except:
        can_sign = is_segwit_address(entry.address)
    if can_sign:
        if not watch_only:
            actions.append([_('Sign/verify Message'), on_sign_verify])
            actions.append([_('Encrypt/decrypt Message'), on_encrypt_decrypt])
        else:
            actions.append([_('Verify Message'), on_sign_verify])

    utils.show_alert(
        vc=parentvc,
        title=_("Options"),
        message=entry.addr_str,  # [0:12] + "..." + entry.addr_str[-12:],
        actions=actions,
        cancel=_('Cancel'),
        style=UIAlertControllerStyleActionSheet,
        ipadAnchor=ipadAnchor)