Exemplo n.º 1
0
    def on_receive(self, keyhash, message):
        self.print_error("signal arrived for", keyhash)
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            self.print_error("keyhash not found")
            return

        wallet = window.wallet
        if wallet.has_keystore_encryption():
            password = window.password_dialog('An encrypted transaction was retrieved from cosigning pool.\nPlease enter your password to decrypt it.')
            if not password:
                return
        else:
            password = None
            if not window.question(_("An encrypted transaction was retrieved from cosigning pool.\nDo you want to open it now?")):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            k = bh2u(bitcoin.deserialize_xprv(xprv)[-1])
            EC = bitcoin.EC_KEY(bfh(k))
            message = bh2u(EC.decrypt_message(message))
        except Exception as e:
            traceback.print_exc(file=sys.stdout)
            window.show_message(str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message)
        show_transaction(tx, window, prompt_if_unsaved=True)
Exemplo n.º 2
0
    def on_receive(self):
        if self.wallet.use_encryption:
            password = self.win.password_dialog('An encrypted transaction was retrieved from cosigning pool.\nPlease enter your password to decrypt it.')
            if not password:
                return
        else:
            password = None
            if not self.win.question(_("An encrypted transaction was retrieved from cosigning pool.\nDo you want to open it now?")):
                return

        message = self.listener.message
        key = self.listener.keyname
        xprv = self.wallet.get_master_private_key(key, password)
        if not xprv:
            return
        try:
            k = bitcoin.deserialize_xkey(xprv)[-1].encode('hex')
            EC = bitcoin.EC_KEY(k.decode('hex'))
            message = EC.decrypt_message(message)
        except Exception as e:
            traceback.print_exc(file=sys.stdout)
            self.win.show_message(str(e))
            return

        self.listener.clear()
        tx = transaction.Transaction(message)
        show_transaction(tx, self.win, prompt_if_unsaved=True)
Exemplo n.º 3
0
    def test_tx_signed_segwit(self):
        tx = transaction.Transaction(signed_segwit_blob)

        self.assertEqual(tx.estimated_total_size(), 223)
        self.assertEqual(tx.estimated_base_size(), 182)
        self.assertEqual(tx.estimated_witness_size(), 41)
        self.assertEqual(tx.estimated_weight(), 769)
        self.assertEqual(tx.estimated_size(), 193)
Exemplo n.º 4
0
    def test_estimated_tx_size(self):
        tx = transaction.Transaction(signed_blob)

        self.assertEqual(tx.estimated_total_size(), 193)
        self.assertEqual(tx.estimated_base_size(), 193)
        self.assertEqual(tx.estimated_witness_size(), 0)
        self.assertEqual(tx.estimated_weight(), 772)
        self.assertEqual(tx.estimated_size(), 193)
Exemplo n.º 5
0
    def on_receive(self, keyhash, message):
        self.print_error("signal arrived for", keyhash)
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            self.print_error("keyhash not found")
            return

        wallet = window.wallet
        if isinstance(wallet.keystore, keystore.Hardware_KeyStore):
            window.show_warning(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' +
                _('However, hardware wallets do not support message decryption, '
                  'which makes them not compatible with the current design of cosigner pool.'
                  ))
            return
        elif wallet.has_keystore_encryption():
            password = window.password_dialog(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' + _('Please enter your password to decrypt it.'))
            if not password:
                return
        else:
            password = None
            if not window.question(
                    _("An encrypted transaction was retrieved from cosigning pool."
                      ) + '\n' + _("Do you want to open it now?")):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            k = bitcoin.deserialize_xprv(xprv)[-1]
            EC = ecc.ECPrivkey(k)
            message = bh2u(EC.decrypt_message(message))
        except Exception as e:
            traceback.print_exc(file=sys.stdout)
            window.show_error(_('Error decrypting message') + ':\n' + str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message,
                                     window.network.get_server_height())
        show_transaction(tx, window, prompt_if_unsaved=True)
Exemplo n.º 6
0
    def on_receive(self, keyhash, message):
        self.logger.info(f"signal arrived for {keyhash}")
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            self.logger.info("keyhash not found")
            return

        wallet = window.wallet
        if isinstance(wallet.keystore, keystore.Hardware_KeyStore):
            window.show_warning(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' +
                _('However, hardware wallets do not support message decryption, '
                  'which makes them not compatible with the current design of cosigner pool.'
                  ))
            return
        elif wallet.has_keystore_encryption():
            password = window.password_dialog(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' + _('Please enter your password to decrypt it.'))
            if not password:
                return
        else:
            password = None
            if not window.question(
                    _("An encrypted transaction was retrieved from cosigning pool."
                      ) + '\n' + _("Do you want to open it now?")):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            privkey = BIP32Node.from_xkey(xprv).eckey
            message = bh2u(privkey.decrypt_message(message))
        except Exception as e:
            self.logger.exception('')
            window.show_error(_('Error decrypting message') + ':\n' + str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message)
        show_transaction(tx, window, prompt_if_unsaved=True)
Exemplo n.º 7
0
 def verify_tx_input(tx, i, script, sig, pub):
     pub, sig, script = (binascii.unhexlify(x) for x in [pub, sig, script])
     t = etr.Transaction(tx)
     t.deserialize()
     #to prepare for verification (to do the txhash for modtx)
     #we need to have the "address" field set in the input.
     typ, addr = etr.get_address_from_output_script(script)
     if not typ == ebt.TYPE_ADDRESS:
         #Don't support non-p2sh, non-p2pkh for now
         log.debug("Invalid script")
         return False
     t.inputs()[i]["address"] = addr
     t.inputs()[i]["type"] = 'p2pkh'
     txforsig = etr.Hash(t.serialize_preimage(i).decode('hex'))
     ecdsa_pub = get_ecdsa_verifying_key(pub)
     if not ecdsa_pub:
         return False
     try:
         verified = ecdsa_pub.verify_digest(sig, txforsig,
                                    sigdecode = sigdecode_der)
     except BadSignatureError, BadDigestError:
         return False
Exemplo n.º 8
0
 def test_tx_deserialize_for_signed_network_tx(self):
     tx = transaction.Transaction(signed_blob)
     tx.deserialize()
     self.assertEqual(1, tx.version)
     self.assertEqual(0, tx.locktime)
     self.assertEqual(1, len(tx.inputs()))
     self.assertEqual(4294967295, tx.inputs()[0].nsequence)
     self.assertEqual(
         bfh('493046022100a82bbc57a0136751e5433f41cf000b3f1a99c6744775e76ec764fb78c54ee100022100f9e80b7de89de861dc6fb0c1429d5da72c2b6b2ee2406bc9bfb1beedd729d985012102e61d176da16edd1d258a200ad9759ef63adf8e14cd97f53227bae35cdb84d2f6'
             ),
         tx.inputs()[0].script_sig)
     self.assertEqual(None, tx.inputs()[0].witness)
     self.assertEqual(
         '3140eb24b43386f35ba69e3875eb6c93130ac66201d01c58f598defc949a5c2a:0',
         tx.inputs()[0].prevout.to_str())
     self.assertEqual(1, len(tx.outputs()))
     self.assertEqual(
         bfh('76a914230ac37834073a42146f11ef8414ae929feaafc388ac'),
         tx.outputs()[0].scriptpubkey)
     self.assertEqual('k112pHc1rbsM4fQDiyUFzkUdtdzr4AQBa2r',
                      tx.outputs()[0].address)
     self.assertEqual(1000000, tx.outputs()[0].value)
     self.assertEqual(tx.serialize(), signed_blob)
Exemplo n.º 9
0
def test_btc():
    #Sign and verify test (for message signing in joinmarket handshake)
    print("Using interface " + interface)
    priv = dbl_sha256("hello") + "01"
    x = ecdsa_sign("helloxxx", priv)
    log.debug("Got: " + x)
    y = ecdsa_verify("helloxxx", x, privkey_to_pubkey(priv))
    log.debug("Sig ver: " + str(y))
    assert y

    #address/script conversion test
    test_addr = "1LT6rwv26bV7mgvRosoSCyGM7ttVRsYidP"
    #Electrum has no support for testnet!
    #test_test_addr = "mgvipZr8kX7fZFQU7QsKTCJT9QCfaiswV7"
    assert script_to_address(address_to_script(test_addr)) == test_addr
    assert get_version_byte(test_addr) == 0

    #Transaction creation test.
    raw_valid_tx = "01000000064cdfe43ad43b187b738644363144784a09bf6d408012409cf9934591109a789b060000006b483045022100d4309edbb8253e62fb59462f2ff5c3445923e0299bf1a15ac5f7db3da5752bee022066f3f219de7e6ee56c3d600da757ec1051cbd11b42969b8935ae35642b6a2e84012102e94b49525342110266a1dc7651221507318c4cb914ede004b3098650e9b951b6ffffffffc2a9b3e8285c2e7aaee2ea50f792172c920c43a675fa8e8d70976727c8752adf030000006a47304402202763d8ad9e41c99c5af587c69d267493773dc9567519a64db8b707af5daf07f0022011729c6d241ad5abe48687d084644bd442b5f9038db04fb28da674126183aca5012102d2cbeb9386fd201bc6eecf27b2858f7bc27462cd9b43ae464e9ef3281f97a3e0ffffffffa787e89792a93111ff08f5a083234c7c2410bd69b6eef42be0fc5f026a3a1cf0030000006b483045022100c3b86d7acadf1be3d8ea6706daedb842b09732621e830440481370d423703741022009fd0f90a07babd481f1011ec883b2aa248c6a4a433599c5b203c6b93fc03b67012103f9a47d3958281b6749921fdf6d9edde0176342c00ced7caacab9ab3a64795086ffffffff23fb90cebcb1784a7a4a0a35489356ba64cf95c0afdc5a0f0184dc22668ff41f050000006b483045022100ea698e5952e23ffdf6d58bdc73e91c555867e3ad99ac9b583f492882395ace9a0220705abe597972d45923fe0515695dd7b99dcfa50e69d49c03a8126180fd263bc70121036532aa886851548a5b62bff29b4c36bfdc33e68c7dbee8efb4b440e50c5ebc6effffffffd401de8afd8fd323ab6abd9db1d261ac69e7c1d2be7f1a40004e7659b7d6cd9b030000006b483045022100b09c4e7f227f2f86d1965edbc4c92b9058243300f3bc62a3169591aacb60ca4d0220390d0d7ae2ee7dab200e166337c65d4a62b576dc4fa138ce40efd240c57346fc0121034cd59665d736d927d9613c7624f8d616d483b06ab8993446f6119f18e22731feffffffff38b8b3ae5fe9ef09c9f1583c9d6cc128bbd2639d49aca97b7686a74ba91bb32a040000006a4730440220105d93aba953edf008cc5b16ac81c10d97db6e59a3e13062ceef7cc1fbffd2ad022027b14b4162d70c4448bec7cb086b4e52880b51b282de98019ec3038153e25ed0012102cdbfb52b3e164203845f72391a3a58205834a3ad473a9d9878488dc1594aa0d4ffffffff087edb0000000000001976a914a1e5f40c6171e91183533f16bbda35e45182bcfa88ac80d97800000000001976a91482985ea6f877d70692072af967af305005fc86fd88ac80d97800000000001976a914a698b206b9f654974afd2056c85c52f88e4c2b2488ac9970af05000000001976a914b05dbb0ede1191e2871209affd8a5922e0a3275288ac80d97800000000001976a914619b3b22b7b66220d22907b8600724aecc49f03488acabc80000000000001976a914911c8c57eb12aa2c1cdce92f82c7e0405a2f3c6988ac80d97800000000001976a91464cd0ed04862f2b7101e9394285d2b3066e5e4dc88ac13b14100000000001976a9143f81fa4fd890845882fbb5226539d9643c99f0f488ac00000000"
    rvtxid = "4489a8cc933cb4e94915ead5b57b4aa707212c1f7b317187b500491e068c7887"
    if interface == "joinmarket-electrum":
        t = etr.Transaction(raw_valid_tx)
        assert rvtxid == t.hash()

        #Transaction deserialization/serialization test
        #Electrum requires this call to fill out Transactionfields
        t.deserialize()
        #log.debug("Got inputs: " + str(t.inputs))
        ourdeser = deserialize(t.raw)
        ourraw = serialize(ourdeser)
        #log.debug("Recreated: \n" + ourraw)
        assert ourraw == raw_valid_tx
        #double check round trip too
        assert deserialize(ourraw) == ourdeser
        txinslist = t.inputs()
    elif interface == "joinmarket-joinmarket":
        assert serialize(deserialize(raw_valid_tx)) == raw_valid_tx
        t = deserialize(raw_valid_tx)
        txinslist = t["ins"]
    else:
        raise NotImplementedError("No such interface?")

    #Transaction signature verification tests.
    #All currently assuming 100% p2pkh.
    for i, tin in enumerate(txinslist):
        if interface == "joinmarket-electrum":
            script = address_to_script(tin["address"])
            sig = tin["signatures"][0]
            pub = tin["pubkeys"][0]
        elif interface == "joinmarket-joinmarket":
            log.debug("Joinmarket working with this script: " + tin["script"])
            scriptSig = tin["script"]
            #We need to parse out the pubkey, convert to address, then convert
            #to a pubkeyscript; this assumes p2pkh. Note that this is handled
            #internally by the joinmarket blockchain/maker/taker code, so only
            #for tests.
            pub = scriptSig[-66:]
            script = address_to_script(pubkey_to_address(pub))
            log.debug("Converted to this addr script: " + script)
            #drop the length bytes from the start of sig and pub
            sig = scriptSig[2:-68]
        else:
            raise NotImplementedError("No such interface?")
        log.debug("Got sig, script, pub: " + " ".join([sig, script, pub]))
        assert verify_tx_input(raw_valid_tx, i, script, sig, pub)
        log.debug("Sig at: " + str(i) + " OK.")

    #Note there are no transaction signing tests, as
    #this is done by the wallet in this interface.
    log.debug("All tests passed.")
Exemplo n.º 10
0
 def txhash(txhex):
     t = etr.Transaction(txhex)
     return t.txid()
Exemplo n.º 11
0
    def test_tx_unsigned(self):
        self.maxDiff = None
        expected = {
            'inputs': [{
                'type':
                'p2pkh',
                'address':
                '14iRdacqJ95JffkUFUTUoZmHCUkq21UMAZ',
                'issuance':
                None,
                'num_sig':
                1,
                'prevout_hash':
                '25554b1cb7c28ca28188066312f66524bf1b241a120dec8bd39e81699aebddf8',
                'prevout_n':
                1,
                'pubkeys': [
                    '031ec67b31750c9ca58b859200267625681d4c9849f8fb163207c4186a273e0b0a'
                ],
                'scriptSig':
                '01ff4c53ff0488b21e000000000000000000350138c626aac760ea9eedb47287f12c4d783910821c5602d5f8ed933a8f0d95025fb1f45ecb87f2089dc8b0257fc23cc5fd13ae9d4e14c08b0398002d68eae14c00000000',
                'sequence':
                4294967294,
                'signatures': [None],
                'x_pubkeys': [
                    'ff0488b21e000000000000000000350138c626aac760ea9eedb47287f12c4d783910821c5602d5f8ed933a8f0d95025fb1f45ecb87f2089dc8b0257fc23cc5fd13ae9d4e14c08b0398002d68eae14c00000000'
                ]
            }],
            'lockTime':
            3,
            'outputs': [{
                'address': '1BvbZykUE5oS5ACH5U4mhwE5KdJPHson7',
                'asset':
                '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4',
                'asset_version': 1,
                'nonce': None,
                'nonce_version': 0,
                'prevout_n': 0,
                'scriptPubKey':
                '76a9140210e63973f9feddf155e5e73ac8f7289549b5f788ac',
                'range_proof': None,
                'surjection_proof': None,
                'type': TYPE_ADDRESS,
                'value': 100000000000000,
                'value_version': 1
            }, {
                'address': '1FRUENS6LR8JdwEoptZwjRA1c64WDgcsac',
                'asset':
                '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4',
                'asset_version': 1,
                'nonce': None,
                'nonce_version': 0,
                'prevout_n': 1,
                'scriptPubKey':
                '76a9149e327995acc97229c07ce5e75789dab5eb3b689188ac',
                'range_proof': None,
                'surjection_proof': None,
                'type': TYPE_ADDRESS,
                'value': 399999999965500,
                'value_version': 1
            }, {
                'address': '',
                'asset':
                '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4',
                'asset_version': 1,
                'nonce': None,
                'nonce_version': 0,
                'prevout_n': 2,
                'scriptPubKey': '',
                'range_proof': None,
                'surjection_proof': None,
                'type': TYPE_SCRIPT,
                'value': 34500,
                'value_version': 1
            }],
            'partial':
            True,
            'segwit_ser':
            False,
            'version':
            1,
        }
        tx = transaction.Transaction(unsigned_blob)
        self.assertEqual(tx.deserialize(), expected)
        self.assertEqual(tx.deserialize(), None)

        self.assertEqual(tx.as_dict(), {
            'hex': unsigned_blob,
            'complete': False,
            'final': True
        })
        self.assertEqual(tx.get_outputs(), [
            ('1BvbZykUE5oS5ACH5U4mhwE5KdJPHson7', 100000000000000,
             '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4'
             ),
            ('1FRUENS6LR8JdwEoptZwjRA1c64WDgcsac', 399999999965500,
             '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4'
             ),
            ('SCRIPT ', 34500,
             '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4'
             )
        ])
        self.assertEqual(tx.get_output_addresses(), [
            '1BvbZykUE5oS5ACH5U4mhwE5KdJPHson7',
            '1FRUENS6LR8JdwEoptZwjRA1c64WDgcsac', 'SCRIPT '
        ])

        self.assertTrue(tx.has_address('1BvbZykUE5oS5ACH5U4mhwE5KdJPHson7'))
        self.assertTrue(tx.has_address('1FRUENS6LR8JdwEoptZwjRA1c64WDgcsac'))
        self.assertFalse(tx.has_address('1FRUENS6LR8JdwEoptZwjRA1c64WDgcsab'))
        self.assertEqual(tx.serialize(), unsigned_blob)

        tx.update_signatures(signed_blob_signatures)
        self.assertEqual(tx.raw, signed_blob)

        tx.update(unsigned_blob)
        tx.raw = None
        blob = str(tx)
        self.assertEqual(transaction.deserialize(blob), expected)
Exemplo n.º 12
0
 def _run_naive_tests_on_tx(self, raw_tx, txid):
     tx = transaction.Transaction(raw_tx)
     self.assertEqual(txid, tx.txid())
     self.assertEqual(raw_tx, tx.serialize())
     self.assertTrue(tx.estimated_size() >= 0)
Exemplo n.º 13
0
 def test_version_field(self):
     tx = transaction.Transaction(v2_blob)
     self.assertEqual(
         tx.txid(),
         "7201a219a30af1303e4c17ab15a02e2d9c6fbfcd162403d5d171f293fa7901ce")
Exemplo n.º 14
0
    def test_tx_signed(self):
        self.maxDiff = None
        expected = {
            'inputs': [{
                'type': 'unknown',
                'address': None,
                'issuance': None,
                'num_sig': 0,
                'prevout_hash':
                '25554b1cb7c28ca28188066312f66524bf1b241a120dec8bd39e81699aebddf8',
                'prevout_n': 1,
                'scriptSig':
                '483045022100c055b7b07847ee98bce64b22058356efca5b81f8a69f8c2b285669081c58361c02202d14691a6909888fc09e6fb2ab37949de87e0c7d1e72db10d6a2bfbec35fe61b0121031ec67b31750c9ca58b859200267625681d4c9849f8fb163207c4186a273e0b0a',
                'sequence': 4294967294
            }],
            'lockTime':
            3,
            'outputs': [
                {
                    'address': '1BvbZykUE5oS5ACH5U4mhwE5KdJPHson7',
                    'asset':
                    '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4',
                    'asset_version': 1,
                    'nonce': None,
                    'nonce_version': 0,
                    'prevout_n': 0,
                    'scriptPubKey':
                    '76a9140210e63973f9feddf155e5e73ac8f7289549b5f788ac',
                    'range_proof': None,
                    'surjection_proof': None,
                    'type': TYPE_ADDRESS,
                    'value': 100000000000000,
                    'value_version': 1
                },
                {
                    'address': '1FRUENS6LR8JdwEoptZwjRA1c64WDgcsac',
                    'asset':
                    '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4',
                    'asset_version': 1,
                    'nonce': None,
                    'nonce_version': 0,
                    'prevout_n': 1,
                    'scriptPubKey':
                    '76a9149e327995acc97229c07ce5e75789dab5eb3b689188ac',
                    'range_proof': None,
                    'surjection_proof': None,
                    'type': TYPE_ADDRESS,
                    'value': 399999999965500,
                    'value_version': 1
                },
                {
                    'address': '',
                    'asset':
                    '6718fdfa571f3f3d091cf57f03ceac534ee5a4f78f80880dc97ee1b4f5c21da4',
                    'asset_version': 1,
                    'nonce': None,
                    'nonce_version': 0,
                    'prevout_n': 2,
                    'scriptPubKey': '',
                    'range_proof': None,
                    'surjection_proof': None,
                    'type': TYPE_SCRIPT,
                    'value': 34500,
                    'value_version': 1
                },
            ],
            'partial':
            False,
            'segwit_ser':
            False,
            'version':
            1,
        }
        tx = transaction.Transaction(signed_blob)
        self.assertEqual(tx.deserialize(), expected)
        self.assertEqual(tx.deserialize(), None)
        self.assertEqual(tx.as_dict(), {
            'hex': signed_blob,
            'complete': True,
            'final': True
        })

        self.assertEqual(tx.serialize(), signed_blob)

        tx.update_signatures(signed_blob_signatures)

        self.assertEqual(tx.estimated_total_size(), 341)
        self.assertEqual(tx.estimated_base_size(), 341)
        self.assertEqual(tx.estimated_witness_size(), 0)
        self.assertEqual(tx.estimated_weight(), 1364)
        self.assertEqual(tx.estimated_size(), 341)
Exemplo n.º 15
0
 def test_version_field(self):
     tx = transaction.Transaction(v2_blob)
     self.assertEqual(
         tx.txid(),
         "dd01e590bad4e115e1894c3c98894fbbdb7a76884b1bb2bfc57e137f9cc8d462")